Subprojects Behind OpenResty
API7.ai
September 12, 2022
Comment extraire le code Lua de nginx.conf
tout en le gardant lisible et maintenable ? La solution est assez simple. Voyons comment implémenter cela avec OpenResty.
Tout d'abord, créez un répertoire appelé lua
. Ensuite, nous y placerons tous les fichiers .lua
.
$ mkdir lua
$ cat lua/hello.lua
ngx.say("hello, world")
Ensuite, utilisez content_by_lua_block
pour remplacer content_by_lua_file
dans le fichier nginx.conf
.
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
server {
listen 8080;
location / {
content_by_lua_file lua/hello.lua;
}
}
}
Enfin, redémarrez les services d'OpenResty, et c'est terminé !
$ sudo kill -HUP `cat logs/nginx.pid`
En utilisant content_by_lua_file
, nous pouvons mettre à jour directement le fichier Lua au lieu de modifier nginx.conf
. Cependant, quelques questions se posent :
- Nous utilisons un chemin relatif dans la section
content_by_lua_file lua/hello.lua
. Comment OpenResty trouve-t-il le fichier Lua réel ? - Après avoir modifié le code Lua, nous devons redémarrer OpenResty pour que cela fonctionne. Existe-t-il un moyen de déboguer efficacement ?
- Comment ajouter le répertoire contenant les fichiers Lua au chemin de recherche d'OpenResty ?
Je vous encourage à réfléchir à ces questions, qui peuvent toutes être résolues dans la documentation officielle. C'est pourquoi j'insiste toujours sur l'importance de la documentation.
Pour la première question, si un chemin relatif est donné, OpenResty ajoutera le préfixe -p PATH
des paramètres de ligne de commande au démarrage et concaténera le chemin relatif en un chemin absolu. Ainsi, OpenResty peut trouver le fichier Lua sans problème.
Le deuxième problème est que le code Lua est chargé lors de la première requête et mis en cache par défaut. Donc, chaque fois que vous modifiez le fichier source Lua, vous devez recharger OpenResty pour que cela fonctionne. Vous pouvez éviter le rechargement en désactivant lua_code_cache
dans nginx.conf
. Cependant, il est essentiel de noter que cette méthode ne doit être utilisée que temporairement pour le développement et le débogage. Si vous déployez en production, vous devez activer le cache. Sinon, cela aura un impact significatif sur les performances.
Pour la dernière question, OpenResty fournit une directive lua_package_path
pour définir le chemin de recherche des modules Lua. Par exemple, nous pouvons définir lua_package_path
à $prefix/lua/?.lua;;
:
$prefix
est le-p PATH
dans les paramètres de démarrage./lua/?.lua
indique tous les fichiers du répertoire Lua avec l'extension.lua
.- Les deux derniers points-virgules représentent le chemin de recherche de code intégré.
Structure du répertoire après installation
Après avoir compris le premier programme hello world, allons au fond des choses et voyons à quoi ressemble la structure du répertoire d'OpenResty après son installation et quels fichiers il contient.
Nous passons d'abord l'option -V
pour voir où se trouve OpenResty. Pour le résultat suivant, j'ai omis de nombreux paramètres de compilation de modules, que nous ajouterons plus tard :
$ openresty -V
nginx version: openresty/1.13.6.2
built by clang 10.0.0 (clang-1000.10.44.4)
built with OpenSSL 1.1.0h 27 Mar 2018
TLS SNI support enabled
configure arguments: --prefix=/usr/local/Cellar/openresty/1.13.6.2/nginx ...
J'utilise brew pour installer OpenResty sur mon Mac. Le chemin est /usr/local/Cellar/openresty/1.13.6.2/nginx
, qui peut différer de votre environnement. Ce chemin contient les répertoires bin
, luajit
, lualib
, nginx
, pod
et d'autres. Il est essentiel de comprendre la signification de ces dossiers pour mieux apprendre OpenResty. Examinons-les donc un par un.
Tout d'abord, le répertoire important bin
.
$ ll /usr/local/Cellar/openresty/1.13.6.2/bin
total 320
-r-xr-xr-x 1 ming admin 19K 3 27 12:54 md2pod.pl
-r-xr-xr-x 1 ming admin 15K 3 27 12:54 nginx-xml2pod
lrwxr-xr-x 1 ming admin 19B 3 27 12:54 openresty -> ../nginx/sbin/nginx
-r-xr-xr-x 1 ming admin 62K 3 27 12:54 opm
-r-xr-xr-x 1 ming admin 29K 3 27 12:54 resty
-r-xr-xr-x 1 ming admin 15K 3 27 12:54 restydoc
-r-xr-xr-x 1 ming admin 8.3K 3 27 12:54 restydoc-index
Ce répertoire contient à la fois l'interface en ligne de commande OpenResty resty
mentionnée dans la section précédente et l'exécutable principal, openresty
, qui est en fait un lien symbolique vers nginx. Quant aux autres outils du répertoire, il ne fait aucun doute que, comme resty
, ce sont tous des scripts Perl.
Parmi eux, opm
est un outil de gestion de paquets qui nous permet de gérer toutes sortes de paquets tiers, qui seront couverts dans une section ultérieure ; et restydoc
, un vieil ami de la première section, est un visualiseur de documentation fourni par OpenResty, qui nous permet de consulter la documentation d'OpenResty et de NGINX.
$ restydoc -s ngx.say
$ restydoc -s proxy_pass
Les deux exemples ci-dessus interrogent respectivement l'API OpenResty et les commandes NGINX. restydoc
est un outil très utile pour les ingénieurs côté serveur qui se concentrent sur le développement.
Après avoir parcouru le répertoire bin
, passons au répertoire pod
.
Tout d'abord, soulignons que pod
ici n'a rien à voir avec le concept de pod dans Kubernetes. Au lieu de cela, pod
est un langage de balisage utilisé en Perl pour écrire la documentation des modules Perl. Et ce répertoire contient la documentation d'OpenResty
, NGINX
, lua-resty-*
et LuaJIT
, qui sont tous liés à restydoc
mentionné précédemment.
Ensuite, les répertoires familiers NGINX
et luajit
. Ces deux-là sont faciles à comprendre. Ils stockent principalement les fichiers exécutables et les dépendances de NGINX et LuaJIT, et sont les pierres angulaires d'OpenResty. Beaucoup de gens disent qu'OpenResty est basé sur Lua, mais ce n'est pas exact. Comme nous pouvons le voir ci-dessus, OpenResty est en fait basé sur LuaJIT.
En fait, dans les premiers temps, OpenResty était livré avec à la fois Lua et LuaJIT, et nous pouvions décider d'utiliser Lua ou LuaJIT via des options de compilation. Cependant, Lua est en train d'être déprécié, et seule la version plus performante LuaJIT est désormais supportée.
Enfin, examinons le répertoire lualib
. Il contient les bibliothèques Lua utilisées dans OpenResty, principalement divisées en deux répertoires : ngx
et resty
.
- Le répertoire
ngx
contient les codes Lua du projet officiel lua-resty-core, qui est une réimplémentation basée sur FFI de l'API OpenResty. J'expliquerai dans un chapitre particulier pourquoi nous devons la réimplémenter. - Le répertoire
resty
contient les codes Lua de divers projetslua-resty-*
, que nous aborderons ensuite.
Suivant la convention de ce cours, à ce stade, je vais donner la source de ces répertoires. C'est aussi l'une des joies des projets open source. Si vous aimez aller au fond des choses, vous trouverez toujours des choses plus intéressantes.
Voici le script de packaging d'OpenResty pour CentOS, qui contient tous les répertoires mentionnés ci-dessus.
%files
%defattr(-,root,root,-)
/etc/init.d/%{name}
/usr/bin/%{name}
%{orprefix}/bin/openresty
%{orprefix}/site/lualib/
%{orprefix}/luajit/*
%{orprefix}/lualib/*
%{orprefix}/nginx/html/*
%{orprefix}/nginx/logs/
%{orprefix}/nginx/sbin/*
%{orprefix}/nginx/tapset/*
%config(noreplace) %{orprefix}/nginx/conf/*
%{orprefix}/COPYRIGHT
Aperçu du projet OpenResty
Lorsqu'on parle d'OpenResty, on pense à lua-nginx-module
. Oui, ce module C NGINX est bien le cœur d'OpenResty, mais il n'est pas équivalent à OpenResty. De nombreux ingénieurs appellent OpenResty ngx + lua
, ce qui est également utilisé dans les livres partagés et publiés lors de nombreuses conférences techniques. Ce n'est pas rigoureux et n'est pas encouragé par la communauté OpenResty.
Permettez-moi de parler de pourquoi et de quels autres projets connexes, en plus de lua-nginx-module
, font partie d'OpenResty.
Ouvrez la page d'accueil du projet OpenResty sur GitHub, et vous verrez qu'OpenResty contient 68 projets publics, qui sont grossièrement divisés en sept catégories. Je vais les présenter brièvement pour que vous puissiez avoir une première impression et les apprendre rapidement.
Modules C NGINX
La dénomination des projets OpenResty est standardisée, et ceux nommés *-nginx-module
sont les modules C NGINX.
Il y a plus de 20 modules C dans OpenResty, et nous pouvons les trouver en utilisant openresty -V
, que nous avons utilisé au début de cette section.
$ openresty -V
nginx version: openresty/1.13.6.2
built by clang 10.0.0 (clang-1000.10.44.4)
built with OpenSSL 1.1.0h 27 Mar 2018
TLS SNI support enabled
configure arguments: --prefix=/usr/local/Cellar/openresty/1.13.6.2/nginx --with-cc-opt='-O2 -I/usr/local/include -I/usr/local/opt/pcre/include -I/usr/local/opt/openresty-openssl/include' --add-module=../ngx_devel_kit-0.3.0 --add-module=../echo-nginx-module-0.61 --add-module=../xss-nginx-module-0.06 --add-module=../ngx_coolkit-0.2rc3 --add-module=../set-misc-nginx-module-0.32 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.08 --add-module=../srcache-nginx-module-0.31 --add-module=../ngx_lua-0.10.13 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.33 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.19 --add-module=../redis2-nginx-module-0.15 --add-module=../redis-nginx-module-0.3.7 --add-module=../ngx_stream_lua-0.0.5 --with-ld-opt='-Wl,-rpath,/usr/local/Cellar/openresty/1.13.6.2/luajit/lib -L/usr/local/lib -L/usr/local/opt/pcre/lib -L/usr/local/opt/openresty-openssl/lib' --pid-path=/usr/local/var/run/openresty.pid --lock-path=/usr/local/var/run/openresty.lock --conf-path=/usr/local/etc/openresty/nginx.conf --http-log-path=/usr/local/var/log/nginx/access.log --error-log-path=/usr/local/var/log/nginx/error.log --with-pcre-jit --with-ipv6 --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_v2_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_auth_request_module --with-http_secure_link_module --with-http_random_index_module --with-http_geoip_module --with-http_gzip_static_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-threads --with-dtrace-probes --with-stream --with-stream_ssl_module --with-http_ssl_module
Ici, --add-module=
est suivi des modules C d'OpenResty. Les principaux sont lua-nginx-module
et stream-lua-nginx-module
, le premier pour gérer le trafic de couche 7 et le second pour piloter le trafic de couche 4.
Certains de ces modules C nécessitent une attention particulière et ne sont pas recommandés, bien qu'ils soient compilés par défaut dans OpenResty. Par exemple, redis2-nginx-module
, redis-nginx-module
et memc-nginx-module
sont utilisés pour interagir avec Redis et Memcached. Ces bibliothèques C étaient recommandées par OpenResty dans les premiers temps, mais ont été remplacées par lua-resty-redis
et lua-resty-memcached
après l'ajout de la fonctionnalité cosocket
, et sont maintenues de manière inactive.
OpenResty ne développera plus de bibliothèques C NGINX à l'avenir, mais se concentrera sur la bibliothèque Lua basée sur cosocket
, qui est l'avenir.
Bibliothèques lua-resty-*
Le dépôt officiel d'OpenResty contient 18 bibliothèques lua-resty-*
, y compris Redis, MySQL, Memcached, WebSocket, DNS, contrôle de trafic, traitement de chaînes, cache en processus et autres bibliothèques standard. En plus de celles officielles qui sont incluses, il existe de nombreuses bibliothèques tierces. Elles sont essentielles, et nous consacrerons plus de temps à ces bibliothèques dans la section suivante.
Branche LuaJIT auto-maintenue
OpenResty maintient sa propre branche LuaJIT en plus de son correctif OpenSSL. En 2015, l'auteur de LuaJIT, Mike Pall, a annoncé sa retraite pour trouver un nouveau mainteneur pour LuaJIT, mais Mike n'a pas trouvé de mainteneur approprié. Il fait maintenant principalement de la maintenance de correctifs, et le développement de nouvelles fonctionnalités a été suspendu, donc OpenResty maintient sa propre branche LuaJIT.
Par rapport à Lua, LuaJIT ajoute de nombreuses fonctions essentielles et uniques, mais peu d'ingénieurs les connaissent, donc ce sont des compétences semi-cachées que je présenterai plus tard.
Cadre de test
Le cadre de test d'OpenResty est test-nginx, également développé en Perl, et comme vous pouvez le voir par son nom, il est spécifiquement conçu pour tester les projets liés à NGINX. Tous les cas de test officiels d'OpenResty pour les modules C et la bibliothèque lua-resty
sont pilotés par test-nginx
. C'est un système beaucoup plus puissant et indépendant, contrairement aux cadres d'assertion courants.
Certains contributeurs d'OpenResty n'ont pas non plus compris ce cadre de test et soumettent parfois des PR contenant du code C et Lua complexe, mais sont souvent intimidés par l'idée d'écrire des cas de test correspondants. Donc, si vous avez regardé certains des cas de test dans le répertoire /t
du projet OpenResty et que vous êtes encore confus, ne doutez pas encore de vous. La plupart des gens sont dans le même cas.
En plus de test-nginx
, le projet mockeagain simule un réseau lent, permettant aux programmes de lire et d'écrire un octet à la fois. C'est un outil très pratique pour les serveurs web.
Chaîne d'outils de débogage
Le projet OpenResty a consacré beaucoup d'efforts à la manière de déboguer le code de manière scientifique et dynamique.
Les deux projets OpenResty, openresty-systemtap-toolkit et stapxx, sont basés sur systemtap
, un outil de débogage et de traçage dynamique. Le plus grand avantage de l'utilisation de systemtap
est qu'il permet une analyse in vivo tout en étant totalement non intrusif pour l'application cible.
Par exemple, un systemtap
est comme aller à l'hôpital et passer un scanner, indolore et imperceptible. Encore mieux, systemtap
peut générer des graphiques enflammés visuels pour l'analyse des performances, que je décrirai plus tard, donc voici un graphique enflammé pour vous donner une idée de ce qui se passe.
Packaging
Les scripts de packaging d'OpenResty pour différents systèmes d'exploitation (comme CentOS, Ubuntu, macOS, etc.) sont écrits à la main pour une meilleure contrôlabilité. Lorsque nous avons présenté la structure du répertoire après l'installation, nous avons déjà couvert ces projets liés au packaging : openresty-packaging et home-brew. Si vous êtes intéressé par cela, vous pouvez l'apprendre vous-même, et je ne le répéterai pas ici.
Outils d'ingénierie
En plus de ces projets plus importants, OpenResty possède plusieurs outils d'ingénierie qui sont pour la plupart cachés.
Par exemple, openresty-devel-utils est l'ensemble d'outils pour développer OpenResty et NGINX. Bien sûr, ils sont également développés en Perl, et la plupart des outils ne sont pas documentés. Mais pour les développeurs d'OpenResty, ces outils sont très pratiques. Je vais en choisir quelques-uns et les présenter brièvement.
- lj-releng est un outil d'inspection de code LuaJIT simple et efficace, similaire à
luacheck
, qui peut trouver des problèmes potentiels avec les variables globales. - reindex, qui signifie reconstruire l'index, est un outil pour formater les cas de test
test-nginx
, réorganiser les numéros de cas de test et supprimer les espaces supplémentaires.reindex
est l'un des outils que les développeurs d'OpenResty utilisent quotidiennement. - opsboy est utilisé pour effectuer des déploiements automatisés. Il est utilisé pour déployer et piloter les tests de régression qu'OpenResty effectue sur des clusters AWS EC2 avant chaque version. Pour plus d'informations, vous pouvez vous référer à la documentation officielle.
opsboy
est un DSL implémenté en Perl. Les auteurs d'OpenResty aiment créer différents DSL pour résoudre des problèmes.
Résumé
Aujourd'hui, nous avons principalement appris la structure du répertoire d'OpenResty après l'installation et certains sous-projets qui le composent. Après avoir appris le contenu d'aujourd'hui, j'espère que vous pourrez en apprendre davantage sur les projets d'OpenResty. OpenResty est allé bien au-delà du champ d'application de l'équilibrage de charge et du proxy inverse de NGINX et a réalisé son propre écosystème. La prochaine fois, nous en parlerons en détail.