OpenResty FAQ | Wie OpenResty in der Praxis eingesetzt wird

API7.ai

February 10, 2023

OpenResty (NGINX + Lua)

  1. Einige Fragen und Antworten zu OpenResty, API-Gateway und Lua
  2. OpenResty FAQ | Privilegierte Prozessberechtigungen, Ausführungsphasen und mehr
  3. OpenResty FAQ | Netzwerkstruktur für Tests, SSL-bezogene Funktionen, DSL, ab-Tool
  4. OpenResty FAQ | Dynamisches Laden, NYI und Caching von Shared Dict

Bisher haben wir den letzten Abschnitt von OpenResty, Microservices API Gateway, abgeschlossen. Herzlichen Glückwunsch, dass Sie nicht zurückgeblieben sind, aktiv gelernt und geübt haben und begeistert Ihre Gedanken hinterlassen haben.

Ich habe hier einige typische und interessante Fragen ausgewählt, um sie mit Ihnen zu teilen. Schauen wir uns heute diese 5 Fragen an.

Frage 1: Wie OpenResty in der Praxis verwendet wird

Beschreibung: Der Kurs ist fast vorbei, und ich kann ihn im Grunde verstehen, aber meine eigene Praxis ist noch gering (derzeit nicht in meiner Arbeit verwendet). Da ich es in meiner Arbeit nicht verwenden kann. Dies ist jedoch eine sehr hilfreiche Artikelserie. Vielen Dank an den Autor für die fortgesetzte Weitergabe, und ich werde es später in meiner Arbeit einführen.

Ich möchte über die Einführung von OpenResty in der Arbeit sprechen, ein Thema, das es wert ist, diskutiert zu werden.

OpenResty basiert auf NGINX und fügt das lua-nginx-module C-Modul und zahlreiche lua-resty-Bibliotheken hinzu, daher ist OpenResty eine gute Alternative für NGINX, was der günstigste Weg ist, um mit OpenResty zu beginnen. Natürlich gibt es Risiken im Zusammenhang mit diesem Ersetzungsprozess, daher müssen Sie die folgenden drei Punkte beachten.

Erstens: Stellen Sie sicher, dass die Online-NGINX-Version mit der Hauptversion von OpenResty übereinstimmt, z. B. OpenResty 1.15.8.1, das NGINX 1.15.8 verwendet. Wenn die aktuelle Online-NGINX-Version höher ist als die neueste Version von OpenResty, müssen Sie vorsichtig auf OpenResty umsteigen. Schließlich ist OpenResty immer noch langsam bei der Aktualisierung und liegt sechs Monate bis ein Jahr hinter der Hauptversion von NGINX zurück. Wenn die Online-NGINX-Version gleich oder niedriger ist als die von OpenResty, dann haben Sie die Voraussetzungen für ein Upgrade.

Zweitens: Tests. Tests sind einer der wichtigsten Aspekte. Es gibt wenig Risiko, OpenResty anstelle von NGINX zu verwenden, aber Risiken bestehen dennoch. Zum Beispiel, ob es benutzerdefinierte C-Module gibt, die kompiliert werden müssen, die Version von openssl, auf die OpenResty angewiesen ist, und ob der Patch, den OpenResty auf NGINX anwendet, Auswirkungen auf das Geschäft hat. Sie müssen einen Teil des Geschäftsverkehrs replizieren, um dies zu überprüfen.

Drittens: Verkehrsumleitung. Nachdem die grundlegende Validierung bestanden ist, müssen Sie immer noch die Canary-Veröffentlichung des echten Verkehrs online überprüfen. Um schnell zurückzurollen, können wir einige neue Server öffnen, um OpenResty bereitzustellen, anstatt den ursprünglichen NGINX-Dienst direkt zu ersetzen. Wenn es keine Probleme gibt, können wir entweder die Binärdatei heiß aktualisieren oder NGINX schrittweise aus dem LB entfernen und ersetzen, um ein Upgrade durchzuführen.

Neben dem Ersetzen von NGINX gibt es zwei weitere einfache Einstiegspunkte für OpenResty: WAF und API-Gateways. Beide sind Szenarien mit hohen Anforderungen an Leistung und Dynamik und haben entsprechende Open-Source-Projekte, die sofort verwendet werden können, die ich zuvor teilweise behandelt habe.

Wenn wir OpenResty auf Geschäftsebene weiter vertiefen, müssen wir über die Technologie hinaus mehr Faktoren berücksichtigen, wie z. B. ob es einfach ist, OpenResty-bezogene Ingenieure zu rekrutieren, ob OpenResty in die bestehenden technischen Systeme des Unternehmens integriert werden kann usw.

Im Allgemeinen ist es eine gute Idee, mit dem Ersetzen von NGINX zu beginnen und dann langsam OpenResty zu verwenden.

Frage 2: Datenbankkapselung für OpenResty

Beschreibung: Laut dem vorherigen Artikel sollten wir den ..-Operator (String-Verkettungsoperator) so wenig wie möglich verwenden, insbesondere im Code-Hot-Path. Aber bei der Datenbankzugriffsverarbeitung muss ich SQL-Anweisungen dynamisch erstellen, indem ich Variablen in die Anweisungen einfüge, was ein gängiges Anwendungsszenario sein sollte. Aber für diese Anforderung fühle ich, dass die String-Verkettung der einfachste Weg ist, und ich kann mir keinen anderen einfachen und leistungsstarken Weg vorstellen.

Sie können es zuerst mit SystemTap oder anderen Tools, die wir in den vorherigen Artikeln vorgestellt haben, analysieren, um zu sehen, ob die Verkettung von SQL-Anweisungen der Engpass des Systems ist. Wenn dies nicht der Fall ist, besteht keine Notwendigkeit, es zu optimieren. Schließlich ist vorzeitige Optimierung die Wurzel allen Übels.

Wenn der Engpass tatsächlich die Verkettung von SQL-Anweisungen ist, dann können wir die Datenbank-prepare-Anweisung verwenden, um die Optimierung durchzuführen, oder ein Array verwenden, um die Verkettung durchzuführen. Aber die Unterstützung für prepare in lua-resty-mysql befindet sich im TODO-Status, daher können wir nur die Array-Verkettung verwenden. Dies ist auch ein häufiges Problem bei einigen lua-resty-Bibliotheken, die den größten Teil der Funktionalität implementieren und normal laufen, aber nicht rechtzeitig aktualisiert werden. Neben der Datenbank-prepare-Anweisung hat lua-resty-redis keine Unterstützung für cluster.

String-Verkettung und lua-resty-Bibliotheken sind die Art von Problemen, die OpenResty vollständig mit DSL lösen möchte - unter Verwendung von Compiler-Technologie, um automatisch Arrays zur String-Verkettung zu generieren, diese Details vor den Benutzern zu verbergen; unter Verwendung von DSL wirelang, um automatisch verschiedene lua-resty-Netzwerkkommunikationsbibliotheken zu generieren, wodurch das manuelle Schreiben entfällt.

Das klingt wunderbar, oder? Aber wir müssen uns einem Problem stellen: Automatisch generierter Code ist für Entwickler unfreundlich. Wenn Sie den generierten Code lernen oder ändern möchten, müssen Sie Compiler-Technologie und eine DSL lernen, die möglicherweise nicht Open-Source ist, was die Barriere für die Teilnahme an der Community immer höher macht.

Frage 3: OpenResty Web Framework

Beschreibung: Ich möchte ein Web-Projekt mit OpenResty erstellen, aber es ist schmerzhaft, hauptsächlich weil ich kein ausgereiftes Framework finden kann und ich viele Räder neu erfinden muss. Zum Beispiel das Problem der Datenbankoperation. Ich habe keine Klassenbibliothek gefunden, die dynamisch SQL-Anweisungen erstellen und kohärente Operationen durchführen kann. Daher möchte ich den Autor fragen, könnten Sie ein gutes Web-Framework empfehlen?

Im Repository awesome-resty können wir sehen, dass es eine spezielle Kategorie für ein Web-Framework gibt, es gibt 20 Open-Source-Projekte, aber die meisten davon sind ins Stocken geraten. Unter ihnen sind Lapis, lor und vanilla drei Projekte, die Sie ausprobieren können, um zu sehen, welches besser geeignet ist.

Tatsächlich ist OpenResty ohne ein starkes Web-Framework überfordert, wenn es um große Projekte geht, was einer der Gründe ist, warum nur wenige Menschen OpenResty für Geschäftssysteme verwenden.

Frage 4: Wie ändert man den content-length im Antwortheader nach der Änderung des Antwortkörpers?

Beschreibung: Wenn ich den Inhalt des Antwortkörpers ändern muss, kann ich nur Änderungen im Body-Filter vornehmen, aber dies führt dazu, dass die Körperlänge nicht mit der content-length-Länge übereinstimmt. Wie sollte ich damit umgehen?

In diesem Fall müssen wir den content-length-Antwortheader in der Header-Filter-Phase vor dem Body-Filter auf nil setzen und ihn nicht zurückgeben und stattdessen die Ausgabe streamen.

Hier ist ein Beispielcode:

server {
    listen 8080;
    location /test {
            proxy_pass http://api7.ai;
            header_filter_by_lua_block {
                     ngx.header.content_length = nil
            }
            body_filter_by_lua_block {
                    ngx.arg[1] = ngx.arg[1] .. "abc"
            }
     }
}

Wie Sie in diesem Code sehen können, repräsentiert ngx.arg[1] in der Body-filter-Phase den Antwortkörper. Wenn wir den String abc danach hinzufügen, wird der Antwortheader content-length ungenau, daher können wir ihn in der Header-Filter-Phase deaktivieren.

Außerdem zeigt dieses Beispiel, wie die verschiedenen Phasen von OpenResty zusammenarbeiten, was ich hoffe, dass Sie bemerken und darüber nachdenken werden.

Frage 5: Lua-Paketpfade in OpenResty

Beschreibung: Der lua_package_path scheint als Suchpfad für Lua-Abhängigkeiten konfiguriert zu sein. Für content_by_lua_file habe ich experimentiert und festgestellt, dass es nur unter dem Präfix basierend auf dem relativen Pfad zur Datei sucht, die durch die Direktive bereitgestellt wird, nicht unter lua_package_path. Ich weiß nicht, ob mein Verständnis korrekt ist.

lua_package_path wird verwendet, um Lua-Module zu laden, zum Beispiel, wenn wir require 'cjson' aufrufen, gehen wir in das Verzeichnis, das in lua_package_path angegeben ist, und suchen nach dem cjson-Modul. Im Gegensatz dazu folgt content_by_lua_file einem Dateipfad auf der Festplatte.

location /test {
     content_by_lua_file /path/test.lua;
 }

Wenn dies kein absoluter Pfad ist, sondern ein relativer Pfad.

 content_by_lua_file path/test.lua;

Dann wird ein Splice mit dem -p-Verzeichnis durchgeführt, das beim Start von OpenResty angegeben wurde, um den absoluten Pfad zu erhalten.

Schließlich sind Sie eingeladen, weiterhin Ihre Fragen im Kommentarbereich zu notieren, und ich werde sie weiterhin beantworten. Ich hoffe, dass ich durch Kommunikation und Fragen und Antworten Ihnen helfen kann, das Gelernte in das Erhaltene umzuwandeln. Sie sind auch eingeladen, diesen Artikel weiterzuleiten, damit wir gemeinsam kommunizieren und uns verbessern können.