Le dernier NGINX est un serveur d'applications! ?? J'ai mesuré le benchmark de NGINX Unit avec PHP, Python, Go! !!

Qu'est-ce que NGINX? ??

image.png

Je vais expliquer brièvement les fonctionnalités de NGINX.

Référence: wikipedia nginx

Dans le passé (bien qu'il y a longtemps), Apache était le secteur des serveurs le plus puissant. Je ne suis pas très familier avec cela, mais comme le serveur est devenu moins cher, le problème C10K est devenu un sujet brûlant dans l'industrie et a été adopté par Apache. Le serveur d'architecture de type pré-Fork qui était autrefois utilisé ne peut plus gérer un grand nombre de requêtes. Parmi eux, NGINX, qui a une architecture événementielle, peut gérer un grand nombre de requêtes et semble avoir attiré l'attention. Par conséquent, NGINX reçoit le tout début de la demande de service Web et l'annule. Il semble que la configuration soit souvent prise. En outre, les sites Web tels que les médias doivent répondre à une vitesse élevée, et il existe de nombreuses caractéristiques qui sont statiques en tant que contenu, il semble donc que NGINX puisse être adopté.

Qu'est-ce que NGINX-Unit? ??

NGIN X-Unit est un produit nouvellement annoncé le 8 septembre 2017. Comme sa caractéristique,

--NGINX Unit est un serveur d'application

Citation: Le serveur d'application "NGINX Unit" est maintenant disponible en open source chez NGINX. Compatible avec PHP, Go et Python. Prise en charge de Java et Node.js

Il semble qu'il y ait une fonctionnalité. En général, il semble que les services Web ont souvent une architecture à trois couches. image.png

Un serveur qui ne renvoie que du HTML statique simple est appelé un serveur Web au sens strict, et un serveur qui exécute un programme écrit en PHP ou Python et peut le lier à HTTP est appelé un serveur d'applications. Jusqu'à présent, j'étais capable de faire quelque chose comme "Exécuter NGINX + gunicorn + Python." Cependant, à proprement parler, les serveurs WSGI (serveur d'applications) tels que gunicorn et NGINX sont uniquement liés. Dans cet exemple, c'est une image que NGINX Unit remplace la partie gunicorn. Je n'ai jamais entendu parler de la fonctionnalité de configuration du serveur par l'API RESTful sur d'autres serveurs. Généralement, c'est une image de mise d'un fichier de paramètres dans / etc / conf et de redémarrage.

Préparer l'environnement

Nous avons procédé à l'environnement de développement tout en empruntant la sagesse de nos prédécesseurs.

J'ai essayé d'exécuter PHP, Python, Golang sur NGINX Unit

Surtout selon la documentation officielle. Cette fois aussi, l'environnement utilise des binaires précompilés sur Ubuntu.

$ wget http://nginx.org/keys/nginx_signing.key
$ sudo apt-key add nginx_signing.key

Ajoutez le texte suivant dans /etc/apt/sources.list

deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ xenial nginx

Et installez

$ sudo apt-get update
$ sudo apt-get install unit unit-dev

Démarrez le serveur

$ sudo service unitd start

L'enquête a pris du temps, mais je pense qu'il est relativement facile de commencer.

En passant, j'ai également regardé les versions php et python de l'unité NGINX incluse ci-dessus.

$ pwd
/usr/lib/unit/modules
$ ls
php.unit.so  python.unit.so

Il semble que php et python soient donc inclus dans / usr / lib / unit / modules. cette

$ objdump -s php.unit.so  | less
$ objdump -s python.unit.so  | less

J'ai lu le vidage binaire visuellement. Par conséquent,

C'était une version comme celle-ci. Probablement parce que le python officiel d'Ubuntu 16.04 est toujours la série 2.7. Si vous souhaitez écrire un programme en série python3, n'y a-t-il pas d'autre choix que de construire à partir du code source?

Paramètres de base du serveur

Cette fois, le code et le fichier de paramètres utilisés dans le benchmark sont préparés dans le référentiel.

https://github.com/kotauchisunsun/nginx_unit_bench

La configuration du serveur est très simple,

$ sudo curl -X PUT -d @php_config.json  \
       --unix-socket /run/control.unit.sock http://localhost/

Ajoutez simplement json comme ceci, et vous pouvez le définir sans redémarrer le serveur. Les points à noter sur Ubuntu sont lancés avec sudo et le socket fonctionne avec /run/control.unit.sock. De plus, json dans le référentiel ne fonctionne pas tel quel. Le chemin du code source à déplacer et le chemin du fichier d'exécution sont écrits sous forme de chemins absolus, veuillez donc les réécrire comme il convient.

référence

Les langages de benchmarking sont PHP, Python et Go. L'application elle-même est très simple

--PHP est "Hello PHP World !!" --Python est "Hello Python World !!" --Go est "Hello Go World !!"

C'est une application qui sort juste. ** Quel est le pont le plus rapide entre l'unité NGINX et le langage de programmation, ce qui le rend aussi simple que possible? Vérifier **.

Le logiciel utilisé pour le benchmark est Apache Bench

Cependant, c'est un outil de test de charge facile à utiliser que j'ai utilisé. La commande ressemble à ceci

$ ab -n 100000 -c 100 http://localhost:8100/ 

Envoyez 100 000 demandes dans 100 parallèles. (Bench.sh dans le référentiel est le script d'exécution pour l'analyse comparative.)

Résultats de référence

Language min Response Time[ms] mean Respones Time[ms] max Response Time[ms] Request Per Second
PHP 6 99 1,414 1005.30
Python 65 141 1,916 708.99
Go 48 106 2,567 946.90

image.png

image.png

Les données détaillées sont placées dans Repository en tant que php.result, python.result, go.result.

Considération

Cela peut être un résultat décevant, mais ** le langage le plus rapide à exécuter sur l'unité NGINX était PHP. ** Pour une raison quelconque, je comprends. Il regarde le code,

index.php


<?php
    echo "Hello PHP World!!";

wsgi.py


from flask import Flask

application = Flask(__name__)


@application.route("/")
def index():
    return "Hello Python World!!"

hello.go


package main

import (
	"fmt"
	"net/http"
	"unit"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello Go World!!")
	})
	unit.ListenAndServe(":8300", nil)
}

Il est. Dans le cas de python, il est nécessaire de créer une application au format wsgi. Par conséquent, il est essentiel de charger les modules Flask et wsgi. Il en est de même pour Go, et il est indispensable de se lier à un module appelé "unit" pour NGINX Unit. D'autre part, PHP ne charge aucune bibliothèque. Personnellement, je me suis dit: "Aller courir en binaire serait le plus rapide." Cependant, ce Go est lent. Et, étant donné que le temps de réponse minimum de PHP est inhabituellement rapide de 6 [ms], en résumé, Python et Go étaient lents et PHP était le plus rapide car le module ** était utilisé. Tu peux voir ça **.

Résumé

--J'ai installé NGINX Unit sur Ubuntu.

Le résultat était. Après tout, ce qui était choquant, c'est que "PHP était le plus rapide", mais honnêtement PHP et Go ne sont pas si différents en termes de performances? Je pense. En fin de compte, Go sera plus rapide à mesure que vous construisez la logique. Je pense. D'un autre côté, Python est-il un peu lent? Je dois ressentir ça. Bien que cela ne soit pas mentionné dans le test de performance ci-dessus, les modules ** Go peuvent ne pas répondre. ** Je n'ai pas tellement retracé la cause, mais pendant le test de charge

apr_socket_recv: Connection reset by peer (104)

A été produit, et il a échoué avec une erreur. Par conséquent, le repère a été repris environ 3 fois au total. L'unité NGINX est toujours comme la version bêta, donc je pense que cela peut arriver. D'un autre côté, ce que je trouve excellent, c'est que vous pouvez configurer le serveur avec REST Full API. C'est fantastique. C'était facile de faire le banc. Cependant, je voulais que vous vous en teniez un peu plus à la création de json. Comme vous pouvez le voir en regardant le json for config dans le référentiel, la notation du chemin est légèrement différente pour chaque langue. J'en suis accro, mais j'ai frappé l'API avec curl sans le remarquer, mais le message d'erreur n'est pas convivial. Le message d'erreur ne m'a pas dit quelle partie de json était erronée, j'ai donc dû jeter un coup d'œil à la documentation officielle tout en ressemblant moi-même à une plaque, ce qui était pénible. Quoi qu'il en soit, une fois que vous vous y êtes habitué, NGINX Unit peut être plus facile. Je n'aime pas PHP. La raison est que vous devez définir open_base_dir etc. dans php.ini (et vous en êtes souvent accro), mais ce côté peut être complètement ignoré et vous pouvez exécuter le code source de n'importe quel chemin. Le réglage peut également être spécifié en une seule fois avec json, c'est donc très simple. C'est également le cas avec Python, et c'est une impression très facile lorsque l'on considère le réglage tout en conservant les paramètres inconnus tels que gunicorn et nginx. De plus, comme il n'est pas nécessaire de redémarrer le serveur, le développement est très simple et Try & Error peut être fait à grande vitesse. Il peut encore être difficile de le mettre en production, mais s'il s'agit d'un produit léger comme Hackason, il est plus facile de gérer le routage et les paramètres que d'utiliser un serveur de langage intégré, j'ai donc pensé que cela pourrait être possible. Veuillez le sentir.

Recommended Posts

Le dernier NGINX est un serveur d'applications! ?? J'ai mesuré le benchmark de NGINX Unit avec PHP, Python, Go! !!
J'ai mesuré la vitesse de la notation d'inclusion de liste, pendant et pendant avec python2.7.
De l'état initial de CentOS8 à l'exécution de php python perl ruby avec nginx
Puisque le memory_profiler de python est lourd, je l'ai mesuré
J'ai mesuré les performances d'un million de documents avec mongoDB
J'ai réfléchi à la raison pour laquelle Python self est nécessaire avec le sentiment d'un interpréteur Python
J'ai créé une application avec Lambda qui notifie LINE de "j'aime" à l'aide de l'API Qiita.
J'ai essayé de trouver l'entropie de l'image avec python
J'ai essayé la "correction gamma" de l'image avec Python + OpenCV
J'ai écrit la grammaire de base de Python dans Jupyter Lab
J'ai évalué la stratégie de négociation du système boursier avec Python.
Exécutons Fusion 360 avec Python Partie 11 Puisqu'il n'y a aucun point le long du chemin dans l'API, j'ai pensé à une alternative
Je souhaite extraire une URL arbitraire de la chaîne de caractères de la source html avec python
L'environnement sans serveur est-il plus de 600 fois plus lent? ~ J'ai essayé l'analyse comparative avec Go, Node.js et Python! ~
J'ai comparé la vitesse de Hash avec Topaz, Ruby et Python
J'ai essayé de gratter le classement du calendrier de l'avent Qiita avec Python
Le 14 mars est le jour du rapport de circonférence. L'histoire du calcul du ratio de circonférence avec python
Je veux sortir le début du mois prochain avec Python
J'ai essayé d'envoyer du courrier depuis le serveur Sakura avec flask-mail
J'ai essayé d'améliorer l'efficacité du travail quotidien avec Python
J'étais fatigué de Python, alors j'ai analysé les données avec nehan (lié à Corona, est-ce que ce mot est maintenant?)
J'ai essayé de sortir la liste rpm de la destination de connexion SSH sur une feuille Excel avec Python + openpyxl.
J'ai aimé le tweet avec python. ..
L'histoire du remontage du serveur d'application
J'ai remplacé le calcul numérique de Python par Rust et comparé la vitesse
Comparer la grammaire de base de Python et Go d'une manière facile à comprendre
J'ai essayé d'obtenir le code d'authentification de l'API Qiita avec Python.
J'ai essayé de rationaliser le rôle standard des nouveaux employés avec Python
J'ai essayé d'obtenir les informations sur le film de l'API TMDb avec Python
Obtenez la valeur de retour d'un script shell externe (ls) avec python3
[Introduction à Python] Quelle est la méthode de répétition avec l'instruction continue?
Explication de la création d'une application pour afficher des images et dessiner avec Python
VS Code se bloque et le PC se bloque lors du lancement du serveur avec go
L'histoire de la migration du serveur domestique (MariaDB + Java) vers AWS (DynamoDB + Python + PHP) avec un coût mensuel réduit
Python> set> Convertir avec set ()> dictionary n'est que la clé> On m'a appris à convertir les valeurs du dictionnaire en set / dir ({}) / help ({}) / help ({} .valeurs)
Je suis un amateur le 14e jour de python, mais je veux essayer l'apprentissage automatique avec scicit-learn
Vérifier l'existence du fichier avec python
Je ne connaissais pas les bases de Python
[python] [meta] Le type de python est-il un type?
Le modèle de projet Python auquel je pense.
Exécutez le serveur python wsgi sur l'unité NGINX
J'ai comparé la vitesse de l'écho du framework web en langage go et du flask du framework web python
J'ai fait une application d'envoi de courrier simple avec tkinter de Python
Je souhaite envoyer Gmail avec Python, mais je ne peux pas en raison d'une erreur
Avec LINEBot, j'ai fait une application qui m'informe de "l'heure du bus"
J'ai essayé d'envoyer automatiquement la littérature du nouveau virus corona à LINE avec Python
J'en ai marre de Python, alors j'ai essayé d'analyser les données avec nehan (je veux aller vivre même avec Corona) -Partie 2)
J'en ai marre de Python, alors j'ai essayé d'analyser les données avec nehan (je veux aller vivre même avec Corona) -Partie 1)