Nginxはctxを使用してデータ共有とコンテキスト変更機能を実現します。

Nginxはctxを使用してデータ共有とコンテキスト変更機能を実現します。

環境: init_worker_by_lua、set_by_lua、rewrite_by_lua、access_by_lua、content_by_lua、header_filter_by_lua、body_filter_by_lua、log_by_lua、ngx.timer.、balancer_by_lua

この Lua テーブルは、リクエストベースの Lua 環境データを保存するために使用でき、その有効期間は現在のリクエストと同じです (Nginx 変数と同様)。

次の例を参照してください。

 場所 /テスト {
  書き換えブロック {
   ngx.ctx.foo = 76
  }
  アクセス_by_lua_ブロック {
   ngx.ctx.foo = ngx.ctx.foo + 3
  }
  コンテンツ_by_lua_block {
   ngx.say(ngx.ctx.foo)
  }
 }

GET /test 出力にアクセスする

79

つまり、ngx.ctx.foo エントリは、リクエストの書き換え、アクセス、およびコンテンツ処理の各フェーズにわたって一貫性を保ちます。

サブリクエストを含む各リクエストには、ngx.ctx テーブルの独自のコピーがあります。例えば:

 場所 /sub {
  コンテンツ_by_lua_block {
   ngx.say("サブプレ: ", ngx.ctx.blah)
   ngx.ctx.blah = 32
   ngx.say("サブ投稿: ", ngx.ctx.blah)
  }
 }

 場所 /main {
  コンテンツ_by_lua_block {
   ngx.ctx.blah = 73
   ngx.say("メイン pre: ", ngx.ctx.blah)
   ローカル res = ngx.location.capture("/sub")
   ngx.print(res.body)
   ngx.say("メイン投稿: ", ngx.ctx.blah)
  }
 }

GET /main出力にアクセスする

メインプレ:73
サブプレ: nil
サブ投稿: 32
メインポスト: 73

ここで、子リクエストの ngx.ctx.blah エントリを変更しても、親リクエストの同じ名前のエントリには影響しません。これは、それぞれが異なるバージョンの ngx.ctx.blah を保持しているためです。

内部リダイレクトにより、元のリクエスト内の ngx.ctx データ (存在する場合) が破棄され、新しいリクエストには空の ngx.ctx テーブルが含まれます。例えば、

 場所 /new {
  コンテンツ_by_lua_block {
   ngx.say(ngx.ctx.foo)
  }
 }

 場所 / 元 {
  コンテンツ_by_lua_block {
   ngx.ctx.foo = "こんにちは"
   ngx.exec("/new")
  }
 }

GET /origにアクセスすると、出力されます

ゼロ

元の「hello」値の代わりに。

この「マジック」テーブルには、Lua クロージャやネストされたテーブルなどの任意のデータ値を挿入することができ、カスタム メタメソッドの登録も可能になります。

ngx.ctxを新しいLuaテーブルで上書きすることも可能です。たとえば、

ngx.ctx = { foo = 32, bar = 54 }

init_worker_by_lua* コンテキストで使用される場合、このテーブルの有効期間は現在の Lua ハンドルと同じになります。

ngx.ctx テーブルの検索には比較的コストのかかるメタメソッド呼び出しが必要であり、これはユーザー独自の関数引数を介してリクエストベースのデータを直接渡すよりもはるかに遅くなります。したがって、パフォーマンスに大きな影響を与える可能性があるため、ユーザー関数パラメータを保存するためにこの API を乱用しないでください。

また、メタメソッドの「マジック」のため、ワーカー レベルのデータ共有など、Lua モジュール レベルで「ローカル」レベルの ngx.ctx を使用しないでください。次の例は良くありません。

-- mymodule.lua

ローカル _M = {}

-- 次の行の ngx.ctx は単一のリクエストに属しますが、ctx 変数は Lua モジュール レベルにあります。

-- そして、それは一人の労働者に属します。

 ローカル ctx = ngx.ctx

 関数_M.main()
  ctx.foo = "バー"
 終わり

 _Mを返す

代わりに以下を使用する必要があります。

 -- mymodule.lua
 ローカル _M = {}

 関数_M.main(ctx)
  ctx.foo = "バー"
 終わり

 _Mを返す

つまり、呼び出し元は関数にパラメータを渡して ctx テーブルへの呼び出しを完了する必要があります。

要約する

上記はこの記事の全内容です。この記事の内容が皆さんの勉強や仕事に一定の参考学習価値を持つことを願っています。ご質問があれば、メッセージを残してコミュニケーションしてください。123WORDPRESS.COM を応援していただきありがとうございます。

以下もご興味があるかもしれません:
  • Nginxでの共有セッション設定方法の例
  • Nginx 負荷分散マルチサイト共有セッション
  • nginx+tomcatは負荷分散を実装し、redisセッション共有を使用します
  • nginx+redisはセッション共有を実現します

<<:  Mysql 5.6ではユーザー名とパスワードを変更するメソッドが追加されました

>>:  React Hooksの使用例

推薦する

Linux 7.7 でスワップ パーティション SWAP を設定する方法

Linux システムの Swap パーティション、つまり swap パーティションは、一般に仮想メモ...

MySQL でよく使用されるデータベースとテーブル シャーディング ソリューションの概要

目次1. データベースのボトルネック2. サブライブラリとサブテーブル2. 横長テーブル3. 垂直サ...

Node.js における非同期プログラミングの知識ポイントの詳細な説明

導入JavaScript はデフォルトでシングルスレッドであるため、コードは並列実行するための新しい...

JS を使用して HTML で回転するクリスマスツリーを実装する

<!DOCTYPE ヘムル パブリック> <html> <ヘッド&g...

MySQL 8.0.24 バージョンのインストールと設定方法のグラフィックチュートリアル

この記事ではMySQL 8.0.24バージョンのインストールと設定方法を記録し、皆さんと共有しますM...

フロントエンドページのスライド検証を実装するための JavaScript + HTML

この記事では、フロントエンドページのスライド検証を実装するためのJavaScript + HTMLの...

MySQL テーブルの読み取り、書き込み、インデックス作成、その他の操作の SQL ステートメントの効率最適化の問題を分析します。

前回は、Explain 実行プランの表示、インデックスの分析など、MySQL での SQL クエリの...

PSSHを使用してLinuxサーバーを一括管理する

pssh は、多数のマシンでのバッチ ssh 操作に使用される、Python で実装されたオープン ...

Node.js での SerialPort モジュールの使用

目次目的モジュールのインストール基本的な使い方ポートをスキャンする開いているポートデータの送信データ...

Mysql マスタースレーブレプリケーションの注意事項の説明

1. マスター'x@xxxx:x'への接続エラー- 再試行時間: 60 再試行回数:...

IE6/7 で絶対配置された要素が不可解に消えたりブロックされたりする問題を解決する方法

1. 絶対配置レイヤーの隣接フローティング レイヤーの幅が親レイヤーの幅と等しくなく、フロートがクリ...

CentOS 8 システム FTP サーバーのインストールとパッシブ モードの設定の詳細なチュートリアル

目次1. 基本を理解する2. システム環境を確認する3. ftpコマンドをインストールする[オプショ...

フロントエンドの vue+express ファイルのアップロードとダウンロードの例

新しいserver.jsを作成する糸初期化 -y 糸を追加エクスプレスノードモン -D var ex...

Linux で一般的なソフトウェアを設定する方法

新しいLinuxサーバーを入手する場合、通常は次の5つの構成を実行する必要があります。 HOSTAN...

Vue で CSS カスタム変数を使用する方法

目次CSS カスタム変数機能は古くから存在していますが、実際の開発ではあまり使用されていません。その...