ブログ | NGINX

njs 0.7.7 で NGINX 構成をさらにモジュール化して再利用可能にする

NGINX-F5 水平黒タイプ RGB の一部
プラバート・ディクシット サムネイル
プラバート・ディクシット
2022年10月20日公開


NGINX JavaScriptモジュール(njs)を導入して以来、2015 (元の名前は nginScript) を開発し、2017 年に一般公開して以来、数十回のバージョン アップデートを通じて、新機能の追加と実装の改良を着実に続けてきました。 通常、NGINX JavaScript の新しいバージョンの機能については NGINX Plus のリリースを待って議論しますが、今回はバージョン 0.7.7 に非常に興奮しており、待ちきれません。

njs 0.7.7 の大幅な機能強化により、NGINX 構成がさらにモジュール化され、整理され、再利用しやすくなります。

njs の詳細と、サンプル コードを提供しているユース ケースの一覧を確認するには、ブログの「NGINX JavaScript モジュールを使用して各リクエストで JavaScript のパワーと利便性を活用する」をお読みください。

njs 0.7.7 のすべての新機能とバグ修正の完全なリストについては、変更点のドキュメントを参照してください。

ローカルコンテキストでの JavaScript コードと変数の宣言

以前の njs バージョンでは、JavaScript コードをインポートし、 js_importjs_pathjs_set 、およびjs_varディレクティブを使用して、最上位のhttpまたはストリームコンテキストで関連する変数を宣言する必要がありました。これは、メイン ファイルの先頭でグローバル変数を宣言するのと同じです。 ただし、実際に JavaScript 関数と変数を呼び出すディレクティブは、子コンテキストに表示されます。たとえば、HTTP location{}ブロック内のjs_contentディレクティブや、Stream server{}ブロック内のjs_accessディレクティブなどです。 これにより、次の 2 つの問題が発生します。

  1. 構成を読んでいる人にとって、 httpおよびstreamコンテキスト内の宣言は、関連するコードと変数が実際にどこで使用されているかが示されていないため、本質的にはノイズです。
  2. 子コンテキストでは、コードと変数がインポートされ宣言された場所が明らかではありません。 メインの設定ファイル ( nginx.conf ) にのみhttp{} ブロックstream{}ブロックを含め、 includeディレクティブを使用して/etc/nginx/conf.dおよび/etc/nginx/stream.dディレクトリから小さな機能固有の設定ファイルを読み込むことをお勧めしますが、NGINX の設定は柔軟であり、複数のファイルにhttp{} ブロックstream{}ブロックを含めることができます。 これは、複数の人が NGINX 構成に取り組んでおり、確立された規則に必ずしも従わない可能性がある環境では特に問題になる可能性があります。

njs 0.7.7 以降では、コードをインポートし、変数が使用されるコンテキストで変数を宣言できます。

特定のユースケースのすべての njs 構成を 1 つのファイルにまとめると、コードのモジュール化と移植性も向上します。

たとえば、以前の njs バージョンでは、新しいスクリプトを追加するときに、 nginx.conf ( js_importと、場合によってはjs_pathjs_setjs_varを追加) と、JavaScript 関数が呼び出されるファイル (ここではjscode_local.conf ) の両方を変更する必要がありました。

njs 0.7.7 以降では、 util 関数に関連するすべての設定はjscode_integrated.conf という1 つのファイルにあります。

実行コンテキストに応じて動作を変更する

njs 0.7.7 のいくつかの新機能により、実行中のコンテキスト (処理フェーズ) に応じて JavaScript コードの動作を変更できるようになりました。

HTTP r.internalプロパティ

HTTP r.internalプロパティは、内部リクエスト ( internalディレクティブを含むlocation{}ブロックによって処理される) に対して「true」に設定されるブール フラグです。 スクリプトが内部コンテキストと非内部コンテキストの両方で呼び出すことができる一般的なイベント ハンドラーを使用する場合は、 r.internalフラグを使用してロジックをフォークできます。

以下は内部リクエストとして分類されます:

  • error_pageindexrandom_indextry_filesディレクティブによってリダイレクトされたリクエスト
  • 上流サーバーからのX-Accel-Redirect応答ヘッダーによってリダイレクトされたリクエスト
  • auth_requestおよびmirrorディレクティブ、 ngx_http_addition_moduleモジュール内のディレクティブ、または Server Side Include (SSI) include仮想コマンド ( ngx_http_ssi_moduleモジュールでサポート) によって呼び出されるサブリクエスト
  • 書き換え指示によって変更されたリクエスト

s.send()ストリーム メソッドの改善

以前の njs バージョンでは、Stream s.send()メソッドはコンテキストに依存します。これは、メソッドが呼び出されるコールバックの場所 (上流または下流) によって、データを送信する方向が決まるためです。 これは、 s.send()が元々設計された同期コールバックでは正常に機能しますが、 ngx.fetch()などの非同期関数では失敗します。

njs 0.7.7 以降では、方向は別の内部フラグに保存され、 s.send()で使用できるようになります。

新しいfs.FileHandle()オブジェクトによるより効率的なファイル操作

ファイル システム モジュール ( fs ) は、ファイルに対する操作を実装します。 fsモジュールの新しいFileHandleオブジェクトは、数値ファイル記述子のオブジェクト ラッパーです。 FileHandleオブジェクトのインスタンスは、fs.promises.open()メソッドによって作成されます。

FileHandleオブジェクトを使用してファイル記述子を取得します。このファイル記述子はさらに次の目的で使用できます。

  • ファイルに対してread()write()などの関数を実行する
  • ファイルを開き、ファイル全体を読み取らずに指定された場所で読み取りと書き込みを実行します。

FileHandleの次のプロパティが実装されています (各プロパティの必須およびオプションの引数の詳細については、ドキュメントを参照してください)。

  • ファイルハンドル.fd
  • ファイルハンドル.read()
  • ファイルハンドル.stat()
  • ファイルハンドル.write()
  • ファイルハンドル.write()
  • ファイルハンドル.close()

これらのメソッドは、 FileHandleをサポートするように更新されました (各メソッドの引数の詳細については、リンクされたドキュメントを参照してください)。

njs を使用して構成を強化する

njs 0.7.7 では、チームが njs コードで作業したり共有したりすることがより容易になりました。 njs ディレクティブの拡張コンテキストにより、カスタム JavaScript コードを使用して NGINX 構成を拡張することがさらに簡単になります。 API ゲートウェイ、リバース プロキシ、または Web サーバーへの第一歩を踏み出すことができます。これは単なるミドルウェアやエッジ コンポーネント以上のものです。 スタックに別のコンポーネントを追加することなく、JavaScript、 TypeScript 、またはサードパーティのノード モジュールを通じてアプリケーションの一部にすることができます。 必要なのはNGINXだけです!

ご質問がありますか? NGINX コミュニティ Slackに参加し、 #njs-code-reviewチャネルをチェックして、詳細を知り、質問し、njs コードに関するフィードバックを得てください。


「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"