BLOG | NGINX

Machen Sie Ihre NGINX-Konfiguration mit njs 0.7.7 noch modularer und wiederverwendbarer

NGINX-Teil-von-F5-horiz-schwarz-Typ-RGB
Prabhat Dixit Miniaturbild
Prabhat Dixit
Veröffentlicht am 20. Oktober 2022


Seit der Einführung des NGINX JavaScript-Moduls (njs) in2015 (unter seinem ursprünglichen Namen nginScript) und der allgemeinen Verfügbarkeit im Jahr 2017<.htmla> haben wir über Dutzende von Versionsaktualisierungen hinweg kontinuierlich neue Funktionen hinzugefügt und unsere Implementierung verfeinert . Normalerweise warten wir auf eine NGINX Plus-Version, um die Funktionen einer neuen NGINX JavaScript-Version zu besprechen, aber wir sind von Version 0.7.7 so begeistert, dass wir es dieses Mal kaum erwarten können!

Die wesentlichen Verbesserungen in njs 0.7.7 tragen dazu bei, Ihre NGINX-Konfiguration noch modularer, übersichtlicher und wiederverwendbarer zu gestalten:

Weitere Informationen zu njs sowie eine Liste der Anwendungsfälle, für die wir Beispielcode bereitstellen, finden Sie in unserem Blog im Artikel „Die Leistung und Benutzerfreundlichkeit von JavaScript für jede Anforderung mit dem NGINX JavaScript-Modul nutzen“ .

Eine vollständige Liste aller neuen Funktionen und Fehlerbehebungen in njs 0.7.7 finden Sie in der Änderungsdokumentation .

Deklarieren von JavaScript-Code und Variablen in lokalen Kontexten

In früheren njs-Versionen mussten Sie Ihren JavaScript-Code importieren und die relevanten Variablen – mit den Anweisungen js_import , js_path , js_set und js_var – im HTTP- oder Stream- Kontext der obersten Ebene deklarieren, was dem Deklarieren globaler Variablen oben in einer Hauptdatei entspricht. Aber die Anweisungen, die tatsächlich die JavaScript-Funktionen und -Variablen aufrufen, erscheinen in einem untergeordneten Kontext – beispielsweise mit der Anweisung js_content in einem HTTP- Location{} -Block und der Anweisung js_access in einem Stream -Server{} -Block. Dies führt zu zwei Problemen:

  1. Für jemanden, der die Konfiguration durchliest, sind die Deklarationen in den HTTP- und Stream- Kontexten im Wesentlichen Rauschen, da es keinen Hinweis darauf gibt, wo der zugehörige Code und die zugehörigen Variablen tatsächlich verwendet werden.
  2. Im untergeordneten Kontext ist nicht offensichtlich, wo der Code und die Variablen importiert und deklariert wurden. Obwohl wir empfehlen, die Blöcke http{} und stream{} nur in die Hauptkonfigurationsdatei ( nginx.conf ) einzubinden und die Direktive „ include “ zu verwenden, um kleinere funktionsspezifische Konfigurationsdateien aus den Verzeichnissen /etc/nginx/conf.d und /etc/nginx/stream.d einzulesen, ist die NGINX-Konfiguration flexibel – Sie können Blöcke http{} und stream{} in mehrere Dateien einbinden. Dies kann insbesondere in Umgebungen problematisch sein, in denen mehrere Personen an Ihrer NGINX-Konfiguration arbeiten und möglicherweise nicht immer etablierte Konventionen befolgen.

In njs 0.7.7 und höher können Sie Code importieren und Variablen in den Kontexten deklarieren, in denen sie verwendet werden:

Wenn sich alle NJS-Konfigurationen für einen bestimmten Anwendungsfall in einer einzigen Datei befinden, wird Ihr Code außerdem modularer und portabler.

Beispielsweise mussten Sie in früheren NJS-Versionen beim Hinzufügen eines neuen Skripts sowohl nginx.conf (durch Hinzufügen von js_import und möglicherweise js_path , js_set und js_var ) als auch die Datei ändern, in der die JavaScript-Funktion aufgerufen wird (hier jscode_local.conf ).

In njs 0.7.7 und höher befindet sich die gesamte Konfiguration im Zusammenhang mit der Util-Funktion in einer einzigen Datei, jscode_integrated.conf :

Ändern des Verhaltens in Abhängigkeit vom Ausführungskontext

Mehrere neue Funktionen in njs 0.7.7 ermöglichen Ihnen, das Verhalten Ihres JavaScript-Codes je nach Kontext (Verarbeitungsphase) zu ändern, in der er ausgeführt wird.

Die HTTP-Eigenschaft r.internal

Die HTTP-Eigenschaft r.internal ist ein boolesches Flag, das für interne Anforderungen (die von location{}- Blöcken verarbeitet werden, die die interne Direktive enthalten) auf „true“ gesetzt ist. Sie können das Flag r.internal verwenden, um die Logik aufzuspalten, wenn ein Skript einen allgemeinen Ereignishandler verwendet, der sowohl in internen als auch in nicht internen Kontexten aufgerufen werden kann.

Als interne Anfragen gelten:

Verbesserte s.send() Stream-Methode

In früheren njs-Versionen war die Stream-Methode s.send() kontextabhängig, da die Richtung, in die sie Daten sendet, durch den Speicherort (upstream oder downstream) des Rückrufs bestimmt wird, an dem die Methode aufgerufen wird. Dies funktioniert gut für synchrone Rückrufe – für die s.send() ursprünglich entwickelt wurde –, schlägt jedoch bei asynchronen Funktionen wie ngx.fetch() fehl.

In njs 0.7.7 und höher wird die Richtung in einem separaten internen Flag gespeichert, das s.send() dann verwenden kann.

Effizientere Dateioperationen mit dem neuen fs.FileHandle() -Objekt

Das Dateisystemmodul ( fs ) implementiert Operationen an Dateien. Das neue FileHandle- Objekt im fs -Modul ist ein Objekt-Wrapper für einen numerischen Dateideskriptor. Instanzen des FileHandle- Objekts werden durch die Methode fs.promises.open() erstellt.

Verwenden Sie das FileHandle -Objekt, um einen Dateideskriptor zu erhalten, der weiter für Folgendes verwendet werden kann:

  • Führen Sie Funktionen wie read() und write() für die Datei aus
  • Öffnen Sie eine Datei und führen Sie Lese- und Schreibvorgänge an einem angegebenen Speicherort aus, ohne die gesamte Datei zu lesen.

Die folgenden Eigenschaften von FileHandle wurden implementiert (Informationen zu den erforderlichen und optionalen Argumenten für jede Eigenschaft finden Sie in der Dokumentation ):

  • Dateihandle.fd
  • Dateihandle.lesen()
  • Dateihandle.stat()
  • Dateihandle.schreiben()
  • Dateihandle.schreiben()
  • Dateihandle.schließen()

Diese Methoden wurden aktualisiert, um FileHandle zu unterstützen (Informationen zu den Argumenten der einzelnen Methoden finden Sie in der verlinkten Dokumentation):

Verwenden Sie njs, um Ihre Konfiguration zu verbessern

Mit njs 0.7.7 haben wir es Ihren Teams einfacher gemacht, an njs-Code zu arbeiten und ihn zu teilen. Die erweiterten Kontexte für NJS-Direktiven machen es noch einfacher, die NGINX-Konfiguration mit benutzerdefiniertem JavaScript-Code zu verbessern. Sie können den ersten Schritt in Richtung eines API-Gateways, Reverse-Proxys oder Webservers machen – und zwar eines, das mehr ist als nur eine weitere Middleware- oder Edge-Komponente. Sie können es über JavaScript, TypeScript oder Knotenmodule von Drittanbietern zu einem Teil Ihrer Anwendung machen, ohne Ihrem Stapel eine weitere Komponente hinzuzufügen. Alles was Sie brauchen ist NGINX!

Habe Fragen? Treten Sie dem NGINX Community Slack bei und sehen Sie sich den Kanal #njs-code-review an, um mehr zu erfahren, Fragen zu stellen und Feedback zu Ihrem NJS-Code zu erhalten.


„Dieser Blogbeitrag kann auf Produkte verweisen, die nicht mehr verfügbar und/oder nicht mehr unterstützt werden. Die aktuellsten Informationen zu verfügbaren F5 NGINX-Produkten und -Lösungen finden Sie in unserer NGINX-Produktfamilie . NGINX ist jetzt Teil von F5. Alle vorherigen NGINX.com-Links werden auf ähnliche NGINX-Inhalte auf F5.com umgeleitet."