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の使用例

推薦する

フロントエンドJavaScriptの動作原理

目次1. JavaScript エンジンとは何ですか? 2. V8エンジン3. ランタイム環境4. ...

JavaScriptはスタック構造の詳細なプロセスを実装する

目次1. スタック構造を理解する2. スタック構造のカプセル化3. 10進数を2進数に変換する1. ...

7つの基本的なXHTMLコーディングルールの概要

1. すべてのタグには対応する終了タグが必要です以前の HTML では、<p> や &l...

Nginx ドメイン名 SSL 証明書の構成 (Web サイトの http を https にアップグレード)

序文HTTP と HTTPS日常生活でよく使われる URL は、おおまかに次の 2 種類に分けられま...

mysqlはルートユーザーと一般ユーザーを作成し、機能を変更および削除します。

方法1: SET PASSWORDコマンドを使用する mysql -u ルート mysql> ...

MySQLサービスが起動しても接続されない問題の解決策

mysql サービスは開始されていますが、接続できません。この問題を解決するにはどうすればよいでしょ...

mysql8.0.19 でパスワードを忘れた場合の完璧な解決策

おすすめの読み物: MySQL 8.0.19 は、間違ったパスワードを 3 回入力するとアカウント ...

CSS で垂直方向の中央揃えを実装するいくつかの方法の概要

フロントエンドのレイアウト プロセスでは、水平方向の中央揃えを実現するのは比較的簡単で、通常は ma...

MySQLは「order by」がどのように機能するかを簡単に理解します

並べ替えの場合、order by は非常に頻繁に使用するキーワードです。インデックスに関するこれまで...

MySQLはフィールドからカンマ区切りの値を取り出して新しいフィールドを形成します

1例: 図1のフィールドを図2に分割するには アカウントIDを選択、 サブストリングインデックス(サ...

CentOS6で定期的にjarプログラムを実行するスクリプトをcrontabで実行する

1. 簡単なJavaプログラムを書く パブリッククラステストシェル{ パブリック静的voidメイン(...

LinuxでTomcatのポート番号を変更する方法

ここには複数の Tomcat があります。それらを同時に使用する場合は、ポート番号を別の番号に変更す...

Vueは動的ルーティングの詳細を実装します

目次1. フロントエンド制御1. router.js ファイル内 (router.js にそれぞれ静...

ウェブページ内でウェブテーブルやdivレイヤーが引き伸ばされる問題の解決策

<br />Web ページをデザインするときには、いつも不快なことに遭遇します。最も一般...

MySQL ステートメントコメントの紹介

MySQL は次の 3 種類のコメントをサポートしています。 1. 行末の「#」文字から。 2. 「...