Subprojects hinter OpenResty
API7.ai
September 12, 2022
Wie extrahiert man Lua-Code aus nginx.conf
und hält ihn lesbar und wartbar? Die Lösung ist recht einfach. Lassen Sie uns sehen, wie dies mit OpenResty implementiert werden kann.
Zuerst erstellen Sie ein Verzeichnis namens lua
. Dann werden wir alle .lua
-Dateien darin ablegen.
$ mkdir lua
$ cat lua/hello.lua
ngx.say("hello, world")
Zweitens verwenden Sie content_by_lua_block
, um content_by_lua_file
in der nginx.conf
-Datei zu ersetzen.
pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
server {
listen 8080;
location / {
content_by_lua_file lua/hello.lua;
}
}
}
Drittens starten Sie die Dienste von OpenResty neu, und schon ist es erledigt!
$ sudo kill -HUP `cat logs/nginx.pid`
Durch die Verwendung von content_by_lua_file
könnten wir die Lua-Datei direkt aktualisieren, anstatt nginx.conf
zu ändern. Es gibt jedoch einige Fragen:
- Wir verwenden einen relativen Pfad im Abschnitt
content_by_lua_file lua/hello.lua
. Wie findet OpenResty die tatsächliche Lua-Datei? - Nach der Änderung des Lua-Codes müssen wir OpenResty neu starten, damit es funktioniert. Gibt es eine Möglichkeit, effizient zu debuggen?
- Wie fügt man das Verzeichnis, das Lua-Dateien enthält, zum Suchpfad von OpenResty hinzu?
Ich ermutige Sie, über diese Fragen nachzudenken, die alle in der offiziellen Dokumentation beantwortet werden können. Deshalb betone ich immer die Bedeutung der Dokumentation.
Für die erste Frage: Wenn der relative Pfad angegeben ist, wird OpenResty beim Start den -p PATH
in den Befehlszeilenparametern des OpenResty-Starts voranstellen und den relativen Pfad in einen absoluten Pfad umwandeln. Auf diese Weise kann OpenResty die Lua-Datei problemlos finden.
Das zweite Problem ist, dass Lua-Code standardmäßig beim ersten Request geladen und zwischengespeichert wird. Daher müssen Sie jedes Mal, wenn Sie die Lua-Quelldatei ändern, OpenResty neu laden, damit die Änderungen wirksam werden. Sie können das Neuladen vermeiden, indem Sie lua_code_cache
in nginx.conf
deaktivieren. Es ist jedoch wichtig zu beachten, dass diese Methode nur vorübergehend für Entwicklung und Debugging verwendet werden sollte. Wenn Sie in der Produktion bereitstellen, müssen Sie den Cache aktivieren. Andernfalls wird dies erhebliche Leistungsauswirkungen haben.
Für die letzte Frage bietet OpenResty die Direktive lua_package_path
, um den Suchpfad für Lua-Module festzulegen. Zum Beispiel können wir lua_package_path
auf $prefix/lua/?.lua;;
setzen:
$prefix
ist der-p PATH
im Startparameter./lua/?.lua
zeigt alle Dateien im Lua-Verzeichnis mit der Endung.lua
an.- Die letzten beiden Semikolons repräsentieren den integrierten Code-Suchpfad.
Verzeichnisstruktur nach der Installation
Nachdem wir das erste Hello-World-Programm verstanden haben, gehen wir ins Detail und sehen, wie die Verzeichnisstruktur von OpenResty nach der Installation aussieht und welche Dateien darin enthalten sind.
Wir verwenden zuerst die Option -V
, um zu sehen, wo OpenResty installiert ist. Für das folgende Ergebnis habe ich viele Modul-Kompilierungsparameter weggelassen, die wir später hinzufügen werden:
$ 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 ...
Ich verwende brew, um OpenResty auf meinem Mac zu installieren. Der Pfad ist /usr/local/Cellar/openresty/1.13.6.2/nginx
, was in Ihrer Umgebung anders sein kann. Dieser Pfad enthält die Verzeichnisse bin
, luajit
, lualib
, nginx
, pod
und andere. Es ist wichtig, die Bedeutung dieser Ordner zu verstehen, damit wir OpenResty besser lernen können. Schauen wir sie uns also nacheinander an.
Zuerst das wichtige bin
-Verzeichnis.
$ 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
Dies enthält sowohl die OpenResty-CLI resty
, die wir im vorherigen Abschnitt erwähnt haben, als auch das Kern-Executable openresty
, das tatsächlich ein symbolischer Link zu nginx ist. Was die anderen Tools im Verzeichnis betrifft, gibt es keinen Zweifel, dass sie, wie resty
, alle Perl-Skripte sind.
Unter ihnen ist opm
ein Paketverwaltungstool, das es uns ermöglicht, alle Arten von Drittanbieterpaketen zu verwalten, was in einem späteren Abschnitt behandelt wird; und restydoc
, ein alter Freund aus dem ersten Abschnitt, ist ein Dokumentationsbetrachter, der von OpenResty bereitgestellt wird und es uns ermöglicht, die Dokumentation von OpenResty und NGINX anzuzeigen.
$ restydoc -s ngx.say
$ restydoc -s proxy_pass
Die beiden obigen Beispiele fragen jeweils die OpenResty-API und die NGINX-Befehle ab. restydoc
ist ein Tool, das für Server-Ingenieure sehr hilfreich ist, um sich auf die Entwicklung zu konzentrieren.
Nachdem wir das bin
-Verzeichnis durchsucht haben, gehen wir weiter zum pod
-Verzeichnis.
Zuerst betonen wir, dass pod
hier nichts mit dem Konzept eines Pods in Kubernetes zu tun hat. Stattdessen ist pod
eine Auszeichnungssprache, die in Perl verwendet wird, um die Dokumentation für Perl-Module zu schreiben. Und dieses Verzeichnis enthält die Dokumentation für OpenResty
, NGINX
, lua-resty-*
und LuaJIT
, die alle mit dem zuvor erwähnten restydoc
verbunden sind.
Als nächstes folgen die vertrauten Verzeichnisse NGINX
und luajit
. Diese beiden sind leicht zu verstehen. Sie speichern hauptsächlich die ausführbaren Dateien und Abhängigkeiten von NGINX und LuaJIT und sind die Grundlagen von OpenResty. Viele Leute sagen, OpenResty basiert auf Lua, aber das ist ungenau. Wie wir oben sehen können, basiert OpenResty tatsächlich auf LuaJIT.
Tatsächlich wurde OpenResty in der Anfangsphase sowohl mit Lua als auch mit LuaJIT ausgeliefert, und wir konnten durch Kompilierungsoptionen entscheiden, ob wir Lua oder LuaJIT verwenden wollten. Aber Lua wird allmählich abgeschafft, und nur das leistungsfähigere LuaJIT wird unterstützt.
Schließlich werfen wir einen Blick auf das lualib
-Verzeichnis. Es enthält die in OpenResty verwendeten Lua-Bibliotheken, die hauptsächlich in zwei Verzeichnisse unterteilt sind: ngx
und resty
.
- Das
ngx
-Verzeichnis enthält die Lua-Codes aus dem offiziellen lua-resty-core-Projekt, das auf der FFI-Neuimplementierung der OpenResty-API basiert. Ich werde in einem speziellen Kapitel erklären, warum wir es neu implementieren müssen. - Das
resty
-Verzeichnis enthält Lua-Code aus verschiedenenlua-resty-*
-Projekten, auf die wir als nächstes eingehen werden.
Gemäß der Konvention dieses Kurses werde ich an dieser Stelle die Quelle dieser Verzeichnisse angeben. Dies ist auch eine der Freuden von Open-Source-Projekten. Wenn Sie gerne bis ins Detail gehen, werden Sie immer wieder spannende Dinge entdecken.
Hier ist das Packaging-Skript von OpenResty für CentOS, das alle oben genannten Verzeichnisse enthält.
%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
Überblick über das OpenResty-Projekt
Wenn wir über OpenResty sprechen, denken wir an lua-nginx-module
. Ja, dieses NGINX-C-Modul ist tatsächlich der Kern von OpenResty, aber es ist nicht gleichbedeutend mit OpenResty. Viele Ingenieure bezeichnen OpenResty als ngx + lua
, was auch in Büchern verwendet wird, die auf vielen technischen Konferenzen geteilt und veröffentlicht werden. Dies ist nicht streng und wird von der OpenResty-Community nicht befürwortet.
Lassen Sie mich erklären, warum und welche anderen verwandten Projekte neben lua-nginx-module
in OpenResty enthalten sind.
Öffnen Sie die Projektseite von OpenResty auf GitHub, und Sie werden sehen, dass OpenResty 68 öffentliche Projekte enthält, die grob in die folgenden sieben Kategorien unterteilt sind. Lassen Sie mich sie kurz vorstellen, damit Sie einen ersten Eindruck bekommen und sie schnell lernen können.
NGINX-C-Module
Die Namensgebung der OpenResty-Projekte ist standardisiert, und diejenigen, die *-nginx-module
heißen, sind die NGINX-C-Module.
Es gibt mehr als 20 C-Module in OpenResty, und wir können sie finden, indem wir openresty -V
verwenden, was wir am Anfang dieses Abschnitts getan haben.
$ 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
Hier folgt auf --add-module=
das C-Modul von OpenResty. Die Kernmodule sind lua-nginx-module
und stream-lua-nginx-module
, wobei ersteres Layer-7-Datenverkehr und letzteres Layer-4-Datenverkehr verarbeitet.
Einige dieser C-Module erfordern besondere Aufmerksamkeit und werden nicht empfohlen, obwohl sie standardmäßig in OpenResty kompiliert werden. Zum Beispiel redis2-nginx-module
, redis-nginx-module
und memc-nginx-module
, die zur Interoperabilität mit Redis und Memcached verwendet werden. Diese C-Bibliotheken wurden in der Anfangsphase von OpenResty empfohlen, wurden jedoch nach der Einführung der Cosocket-Funktion durch lua-resty-redis
und lua-resty-memcached
ersetzt und werden nicht mehr aktiv gepflegt.
OpenResty wird in Zukunft keine weiteren NGINX-C-Bibliotheken entwickeln, sondern sich auf die cosocket-basierten
Lua-Bibliotheken konzentrieren, die die Zukunft sind.
lua-resty-* Bibliotheken
Das offizielle OpenResty-Repository enthält 18 lua-resty-*
-Bibliotheken, darunter Redis, MySQL, Memcached, WebSocket, DNS, Verkehrskontrolle, String-Verarbeitung, In-Process-Caching und andere Standardbibliotheken. Neben den offiziellen, die mitgeliefert werden, gibt es noch mehr Drittanbieterbibliotheken. Sie sind essentiell, und wir werden uns im nächsten Abschnitt mehr Zeit für diese Bibliotheken nehmen.
Eigenständig gepflegter LuaJIT-Zweig
OpenResty pflegt neben seinem eigenen OpenSSL-Patch auch seinen LuaJIT-Zweig. Im Jahr 2015 kündigte der Autor von LuaJIT, Mike Pall, seinen Ruhestand an, um einen neuen LuaJIT-Maintainer zu finden, aber Mike hat keinen geeigneten Maintainer gefunden. Er führt jetzt hauptsächlich Bugfix-Wartung durch, und die Entwicklung neuer Funktionen wurde eingestellt, daher pflegt OpenResty seinen eigenen LuaJIT-Zweig.
Im Vergleich zu Lua fügt LuaJIT viele wichtige und einzigartige Funktionen hinzu, aber nicht viele Ingenieure kennen sie, daher sind sie halb versteckte Fähigkeiten, die ich später vorstellen werde.
Testframework
Das Testframework von OpenResty ist test-nginx, ebenfalls in Perl entwickelt, und wie der Name schon sagt, ist es speziell für die Tests von NGINX-bezogenen Projekten gedacht. Alle offiziellen Testfälle von OpenResty für C-Module und die lua-resty
-Bibliothek werden von test-nginx
angetrieben. Dies ist ein viel leistungsfähigeres und unabhängigeres System, im Gegensatz zu den üblichen assert-basierten Frameworks.
Einige OpenResty-Mitarbeiter haben dieses Testframework noch nicht ganz verstanden und reichen manchmal PRs ein, die komplexen C- und Lua-Code enthalten, aber oft noch von der Idee eingeschüchtert sind, entsprechende Testfälle zu schreiben. Wenn Sie sich also einige der Testfälle im /t
-Verzeichnis des OpenResty-Projekts angesehen haben und immer noch verwirrt sind, zweifeln Sie nicht an sich. Die meisten Leute sind genauso.
Neben test-nginx
simuliert das mockeagain-Projekt ein langsames Netzwerk, sodass Programme Byte für Byte lesen und schreiben können. Dies ist ein sehr nützliches Tool für Webserver.
Debug-Toolchain
Das OpenResty-Projekt hat viel Aufwand in die Frage gesteckt, wie man Code wissenschaftlich und dynamisch debuggen kann.
Die beiden OpenResty-Projekte openresty-systemtap-toolkit und stapxx basieren auf systemtap
, einem dynamischen Debugging- und Tracing-Tool. Der größte Vorteil der Verwendung von systemtap
besteht darin, dass es eine In-vivo-Analyse ermöglicht, während es für die Zielanwendung völlig nicht-invasiv ist.
Zum Beispiel ist systemtap
wie ein CT-Scan im Krankenhaus, schmerzfrei und nicht wahrnehmbar. Noch besser ist, dass systemtap
visuelle Flame-Graphs für die Leistungsanalyse generieren kann, die ich später beschreiben werde. Hier ist ein Flame-Graph, um Ihnen einen Eindruck zu vermitteln.
Paketierung
Die Paketierungsskripte von OpenResty in verschiedenen Betriebssystemen (wie CentOS, Ubuntu, macOS usw.) sind handgeschrieben, um eine bessere Kontrollierbarkeit zu gewährleisten. Als wir die Verzeichnisstruktur nach der Installation vorgestellt haben, haben wir bereits diese paketierungsbezogenen Projekte behandelt: openresty-packaging und home-brew. Wenn Sie daran interessiert sind, können Sie es selbst lernen, und ich werde es hier nicht wiederholen.
Engineering-Tools
Neben diesen größeren Projekten hat OpenResty mehrere Engineering-Tools, die meist versteckt sind.
Zum Beispiel ist openresty-devel-utils das Toolset für die Entwicklung von OpenResty und NGINX. Natürlich sind sie auch in Perl entwickelt, und die meisten Tools sind undokumentiert. Aber für OpenResty-Entwickler sind diese Tools sehr nützlich. Ich werde einige auswählen und kurz vorstellen.
- lj-releng ist ein einfaches und effektives LuaJIT-Code-Inspektionstool, ähnlich wie
luacheck
, das potenzielle Probleme mit globalen Variablen finden kann. - reindex, was bedeutet, den Index neu zu erstellen, ist ein Tool zum Formatieren von
test-nginx
-Testfällen, zum Neuanordnen von Testfallnummern und zum Entfernen von überflüssigem Leerraum.reindex
ist eines der Tools, die OpenResty-Entwickler täglich verwenden. - opsboy wird für automatisierte Bereitstellungen verwendet. Es wird verwendet, um die Regressionstests, die OpenResty vor jeder Veröffentlichung auf AWS-EC2-Clustern durchführt, zu deployen und zu steuern. Weitere Informationen finden Sie in der offiziellen Dokumentation.
opsboy
ist eine in Perl implementierte DSL. Die Autoren von OpenResty mögen es, verschiedene DSLs zu erstellen, um Probleme zu lösen.
Zusammenfassung
Heute haben wir hauptsächlich die Verzeichnisstruktur von OpenResty nach der Installation und einige der dahinterstehenden Unterprojekte kennengelernt. Nachdem Sie den heutigen Inhalt gelernt haben, hoffe ich, dass Sie mehr über die Projekte von OpenResty lernen können. OpenResty ist weit über den Bereich von NGINX-Lastausgleich und Reverse-Proxy hinausgegangen und hat seine eigene Ökologie realisiert. Nächstes Mal werden wir dies im Detail besprechen.