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

推薦する

VueのRender関数

目次1. ノード、ツリー、仮想DOM 2. 仮想DOM 2.1 データオブジェクトの詳細2.2 制約...

レスポンシブレイアウトについて知っておくべきこと

1. はじめにレスポンシブ Web デザインにより、Web サイトは複数のデバイスと複数の画面に同時...

LinuxのCentos7でmysql5.7.29を構築する詳細なプロセス

1. MySQLをダウンロードする1.1 ダウンロードアドレスhttps://downloads.m...

MySQL sql_modeの適切な設定に関する詳細な説明

MySQL sql_modeの適切な設定sql_mode は見落とされやすい変数です。デフォルト値は...

MySQL explain クエリ命令情報の取得原理と例

explain はクエリ実行プラン情報を取得するために使用されます。 1. 文法次のように、sele...

React+Typescriptはカウントダウンフックメソッドを実装します

まず、setIntervalはフックとしてカプセル化されます👇 'react' から...

MySQL パーティションテーブルの正しい使用方法

MySQL パーティションテーブルの概要数億、あるいは数十億ものレコードを格納するテーブルに遭遇する...

Linux SSHポートを転送する3つの方法

ssh は私が最も頻繁に使用する 2 つのコマンドライン ツールのうちの 1 つです (もう 1 つ...

Windows Server 2016 に Docker をインストールする方法

最近、Microsoft は Docker をネイティブにサポートする Windows Server...

jQueryカルーセル機能を実装する方法

この記事では、jQueryカルーセル機能の実装コードを参考までに共有します。具体的な内容は次のとおり...

WeChatアプレットAmapマルチポイントルート計画プロセス例の詳細な説明

電話Amap API を呼び出す方法は? Amap が https://lbs.amap.com/a...

CSS で透明なグラデーション効果を実装するためのサンプルコード

Zhihu Discovery コラムのタイトル画像は、通常、以下のように表示されます。明らかに、グ...

MySQLコンテナ間のレプリケーション構成例の詳細な説明

背景先週、会社で MySQL レプリケーションのトレーニングを受けたので、今週末は学んだことを実践す...

HTML <!--...--> コメントタグの役割の詳細な分析

多くのウェブサイトのソースコードを確認すると、多くのコメントが見つかります。特に、ソース文書にコメン...

LinuxでVIMエディタを使う方法

豊富なオプションを備えた強力なエディターとして、Vim は多くのユーザーに愛されています。この記事で...