ホームページ > 運用・保守 > Nginx > Nginx で上流モジュールを使用する方法

Nginx で上流モジュールを使用する方法

WBOY
リリース: 2023-05-13 08:40:12
転載
1719 人が閲覧しました

アップストリーム モジュールの紹介

  • nginx モジュールは、通常、ハンドラー、フィルター、アップストリームの 3 つのカテゴリに分類されます。前の章で、読者はハンドラーとフィルターについてすでに学習しました。これら 2 種類のモジュールを使用すると、nginx はスタンドアロン作業を簡単に完了できます。

  • アップストリーム モジュールにより、nginx は単一マシンの制限を超え、ネットワーク データの受信、処理、転送を完了できるようになります。

  • データ転送機能は、nginx に単一マシンにわたる水平処理機能を提供し、ターミナル ノードに単一の機能のみを提供するという制限から nginx を解放し、ネットワーク アプリケーション レベルを持つことができるようにします。逆アセンブリ: 機能を分割、カプセル化し、統合します。

  • データ転送は、ネットワーク アプリケーションを構築する nginx の機能の重要なコンポーネントです。もちろん、開発コストの問題により、ネットワーク アプリケーションの主要コンポーネントは、最初は高級プログラミング言語を使用して開発されることがよくあります。しかし、システムがある程度の規模に達し、パフォーマンスがより重視されるようになると、必要なパフォーマンス目標を達成するために、高級言語で開発されたコンポーネントの構造を変更する必要があります。

現時点では、変更コストの観点からは、nginx のアップストリーム モジュールが本質的に高速であるため、その利点が示されています。余談ですが、nginx の構成システムによって提供される階層的で疎結合により、システムは比較的高いレベルまで拡張可能になります。

アップストリーム モジュール インターフェイス

本質的には、アップストリームはハンドラーに属しますが、独自のコンテンツを生成するのではなく、バックエンド サーバーにリクエストしてコンテンツを取得するため、アップストリームと呼ばれます。 (上流の) 。リクエストとレスポンスコンテンツの取得のプロセス全体は nginx 内にカプセル化されているため、上流モジュールはいくつかのコールバック関数を開発するだけで、リクエストの構築やレスポンスの解析などの特定の作業を完了できます。

上流モジュールのコールバック関数は次のとおりです。

#finalize_requestこの関数は、バックエンド サーバーとのリクエストが正常に完了した後に呼び出されます。abort_request と同じであり、通常は特定の作業は実行されません#input_filterinput_filter_init を直接返します。

memcached モジュール分析

  • memcache は、広く使用されている高性能分散キャッシュ システムです。 memcache は、HTTP リクエストを通じて memcache にアクセスできないように、プライベート通信プロトコルのセットを定義します。ただし、プロトコル自体はシンプルで効率的であり、memcache は広く使用されているため、最新の開発言語とプラットフォームのほとんどは、開発者が memcache を使用しやすくするために memcache サポートを提供しています。

  • nginx は ngx_http_memcached モジュールを提供します。これは、memcache からデータを読み取る機能を提供しますが、memcache にデータを書き込む機能は提供しません。

上流モジュールはハンドラー モジュールのアクセス メソッドを使用します。

同時に、上流モジュールの命令システムの設計もハンドラー モジュールの基本ルールに従います。モジュールは、モジュールを構成した後にのみ実行されます。

それでは、アップストリーム モジュールの何が特別なのでしょうか?それが上流モジュールの処理関数です。上流モジュールの処理関数によって実行される操作には、固定のプロセスが含まれます: (memcached モジュールを例として、memcached の処理関数 ngx_http_memcached_handler 内)

Create上流のデータ構造:

ngx_http_upstream_t            *u;
if (ngx_http_upstream_create(r) != NGX_OK) {
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
u = r->upstream;
ログイン後にコピー

モジュールのタグとスキーマを設定します。現在、スキーマはログにのみ使用され、タグは buf_chain 管理に使用されます:

ngx_str_set(&u->schema, "memcached://");
u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module;
ログイン後にコピー

上流のバックエンド サーバー リスト データ構造を設定します:

mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
u->conf = &mlcf->upstream;
ログイン後にコピー

上流のコールバック関数を設定します:

u->create_request = ngx_http_memcached_create_request;
u->reinit_request = ngx_http_memcached_reinit_request;
u->process_header = ngx_http_memcached_process_header;
u->abort_request = ngx_http_memcached_abort_request;
u->finalize_request = ngx_http_memcached_finalize_request;
   
u->input_filter_init = ngx_http_memcached_filter_init;
u->input_filter = ngx_http_memcached_filter;
ログイン後にコピー

アップストリーム環境のデータ構造を作成して設定する:

ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t));
if (ctx == NULL) {
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
ctx->request = r;

ngx_http_set_ctx(r, ctx, ngx_http_memcached_module);

u->input_filter_ctx = ctx;
ログイン後にコピー

アップストリームの初期化と仕上げ作業を完了する:

r->main->count++;
ngx_http_upstream_init(r);
return NGX_DONE;
ログイン後にコピー

これは、memcached のように単純なものから、プロキシのように複雑なものまで、あらゆるアップストリーム モジュールに当てはまります。そしてfastcgi。
これらの 6 つのステップにおけるさまざまなアップストリーム モジュール間の最大の違いは、ステップ 2、3、4、および 5 に現れます。

ステップ 2 と 4 は理解しやすいですが、モジュールごとに設定されるフラグと使用されるコールバック関数は明らかに異なります。ステップ5も理解するのは難しくありません。

ステップ 3 だけが少しわかりにくいです。バックエンド サーバー リストを取得する際、モジュールによって戦略が大きく異なります。memcached のように単純で明確なものもあれば、プロキシのように論理的に複雑なものもあります。

ステップ 6 は通常、異なるモジュール間で一貫しています。 count を 1 増やして NGX_DONE を返します。
nginx はこの状況に遭遇すると、現在のリクエストの処理が終了したとみなしますが、リクエストで使用されていたメモリ リソースを解放したり、クライアントとの接続を閉じたりしません。
これが必要な理由は、nginx がアップストリーム リクエストとクライアント リクエストの間に 1 対 1 の関係を確立しているためです。その後、ngx_event_pipe を使用してアップストリーム レスポンスをクライアントに送り返すときに、これらの保存されたクライアント情報も使用されます。 。 データ構造。
アップストリーム リクエストとクライアント リクエストを 1 対 1 でバインドします。この設計には長所と短所があります。利点は、モジュール開発が簡素化され、モジュール ロジックに集中できることですが、欠点も同様に明白で、多くの場合、1 対 1 設計では複雑なロジックのニーズを満たすことができません。

コールバック関数: (引き続き memcached モジュールの処理関数を例として取り上げます)

  • ngx_http_memcached_create_request: コールバック関数を生成するのは非常に簡単です設定されたコンテンツ キーに従って、「get $key」リクエストを生成し、r->upstream->request_bufs に配置します。

  • ngx_http_memcached_reinit_request: 初期化は必要ありません。

  • ngx_http_memcached_abort_request: 追加のアクションは必要ありません。

  • ngx_http_memcached_finalize_request: 追加のアクションは必要ありません。

  • ngx_http_memcached_process_header: モジュールのビジネス フォーカス機能。 memcache プロトコルのヘッダー情報はテキストの最初の行として定義されており、コードは次のとおりです:

#define LF     (u_char) '\n'
for (p = u->buffer.pos; p < u->buffer.last; p++) {
    if (*p == LF) {
        goto found;
    }
}
ログイン後にコピー

LF (‘\n’) 文字が見つからない場合バッファに読み込まれたデータの場合、関数は NGX_AGAIN を返します。これは、ヘッダーが完全に読み取られておらず、データの読み取りを続ける必要があることを示します。 nginx は、新しいデータを受信した後、この関数を再度呼び出します。

nginx は、バックエンド サーバーの応答ヘッダーを処理するときに 1 つのキャッシュのみを使用します。すべてのデータはこのキャッシュ内にあるため、ヘッダー情報を解析するときに、ヘッダー情報が複数のキャッシュにまたがります。ヘッダーが大きすぎてこのキャッシュに保存できない場合、nginx はクライアントにエラー メッセージを返し、キャッシュが十分に大きくないことを示すエラー ログを記録します。

ngx_http_memcached_process_header の重要な役割は、バックエンド サーバーから返されたステータスをクライアントに返されたステータスに変換することです。例:

u->headers_in.content_length_n = ngx_atoof(start, p - start);
···
u->headers_in.status_n = 200;
u->state->status = 200;
···
u->headers_in.status_n = 404;
u->state->status = 404;
ログイン後にコピー

u->state は、上流関連の変数を計算するために使用されます。たとえば、u->state->status は、変数「upstream_status」の値を計算するために使用されます。 u->headers_in は、クライアントへの応答でステータス コードとして返されます。そして、u->headers_in.content_length_n は、クライアントに返される応答の長さを設定します。

この関数では、ヘッダー情報の処理後に読み取りポインター pos を後方に移動する必要があります。そうしないと、このデータがクライアントに返される応答の本文にもコピーされ、本文の内容が次のようになります。矛盾していますが、正しいです。

ngx_http_memcached_process_header 関数は、応答ヘッダーの正しい処理を完了し、NGX_OK を返す必要があります。 NGX_AGAIN が返された場合は、完全なデータが読み取られていないため、バックエンド サーバーからデータを引き続き読み取る必要があることを意味します。 NGX_DECLINED を返すことは無意味であり、それ以外の戻り値はエラー ステータスとみなされ、nginx はアップストリーム リクエストを終了し、エラー メッセージを返します。

ngx_http_memcached_filter_init: バックエンド サーバーから受信したコンテンツの長さを修正しました。これは、ヘッダーの処理時に長さのこの部分が追加されないためです。

ngx_http_memcached_filter:
memcached モジュールは、テキストを処理するためのコールバック関数を備えた珍しいモジュールです。
memcached モジュールはテキストの終わりにある CRLF "END" CRLF をフィルターする必要があるため、独自のフィルター コールバック関数を実装します。

テキストを処理するという実際の意味は、バックエンド サーバーから受信したテキストの有効な内容を ngx_chain_t にカプセル化し、それを u->out_bufs の最後に追加することです。

nginx はデータをコピーしませんが、これらのデータ メモリ領域を指す ngx_buf_t データ構造を確立し、ngx_chain_t によってこれらの buf を編成します。この実装により、大規模なメモリ再配置が回避され、nginx が効率的である理由の 1 つとなります。

関数名 説明
create_request バックエンドサーバーに送信するリクエストバッファ(バッファチェーン)を生成し、上流の初期化時に使用します
reinit_request バックエンド サーバーでエラーが発生した場合、nginx は別のバックエンド サーバーを試行します。 nginx は新しいサーバーを選択した後、最初にこの関数を呼び出してアップストリーム モジュールの動作ステータスを再初期化し、次にアップストリームに再度接続します
process_header バックエンドの処理サーバーから返された情報ヘッダー。いわゆるヘッダーは、HTTP プロトコルのヘッダー部分や memcached プロトコルの応答ステータス部分など、上流サーバーと通信するためのプロトコルによって指定されます
abort_request クライアントでの中止 要求されたときに呼び出されます。関数内にバックエンド サーバー接続を閉じる関数を実装する必要はありません。システムが接続を閉じる手順を自動的に完了するため、通常、この関数は特定の作業を実行しません
バックエンド サーバーを処理します。返された応答本文。 nginx のデフォルトの input_filter は、受信したコンテンツをバッファー チェーン ngx_chain にカプセル化します。このチェーンはアップストリームの out_bufs ポインター フィールドによって配置されるため、開発者はこのポインターを使用して、モジュールの外部のバックエンド サーバーから返されるテキスト データを取得できます。 memcached モジュールは独自の input_filter を実装していますが、このモジュールについては後で詳しく分析します。
入力フィルター コンテキストを初期化します。 nginx のデフォルトの input_filter_init は

以上がNginx で上流モジュールを使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート