OpenResty におけるリクエスト間のデータ共有
このチュートリアルでは、OpenResty アプリケーションサービスの異なる HTTP リクエスト間でデータを共有する方法を段階的に説明します。
cd ~/
mkdir data-share
cd data-share/
mkdir conf logs lua
tree
まず、テストアプリケーションのディレクトリ構造を準備します。
リクエスト間でデータを共有する簡単な方法は、lua/my-module.lua
という名前のカスタム Lua モジュールを使用することです。
以下の編集を行います:
- このモジュールのトップレベルにグローバルカウンター変数を追加します。
- 次に、
main
という名前のモジュール関数内で常にこのカウンターをインクリメントします。 - そして、新しいカウンター値を返します。
local _M = {}
local counter = 0
function _M.main()
counter = counter + 1
return counter
end
return _M
次に、nginx 設定ファイル conf/nginx.conf
を作成します。
以下の編集を行います:
- ここで、Lua モジュールを探す場所を指定します。
- 次に、ローカルの 8080 ポートでリッスンするサーバーを定義します。
- ルートロケーションには
content_by_lua_block
があります。 - Lua モジュールをロードし、その
main
関数を呼び出します。 - 返されたカウンター値をレスポンスボディとして出力します。
worker_processes 1;
events {
worker_connections 1024;
}
http {
lua_package_path "$prefix/lua/?.lua;;";
server {
listen 8080;
location / {
default_type text/plain;
content_by_lua_block {
local mod = require "my-module"
local cnt = mod.main()
ngx.say("counter = ", cnt)
}
}
}
}
ディレクトリ構造を確認しましょう。
tree .
良さそうですね。
sudo
を使用せずに この OpenResty アプリケーションを起動します。
openresty -p $PWD/
ここでは、1 つのワーカープロセスのみを有効にしています。
ps aux|grep nginx|grep -v tmp
curl
を使用してサーバーに HTTP リクエストを送信します。
curl 'http://127.0.0.1:8080/'
カウンターの値は 1 です。
もう一度試してみましょう:
素晴らしいですね。今度は 2 になりました。
これは継続的に増加していきます。
この counter
Lua 変数が共有されているのは、Lua モジュール関数の アップバリュー
(upvalue)だからです。
cat lua/my-module.lua
そして、Lua モジュールはグローバルな LuaJIT 仮想マシン内でキャッシュされ、共有されています。
resty -Ilua -e 'require "my-module" print(package.loaded["my-module"].main)'
ご覧のとおり、キャッシュされた Lua モジュールに直接アクセスすることもできます。
package.loaded
グローバルテーブルには、ロードされたすべての Lua モジュールが保存されています。
resty -e 'for k, v in pairs(package.loaded) do print(k) end'
ここでは、ほとんどのモジュールが標準モジュールです。
ただし、制限があります。これらのデータは異なる nginx ワーカープロセス間で共有できません。
ここでは問題ありません。1 つのワーカープロセスのみが設定されているからです。
しかし、通常は複数の CPU コアを活用するために複数のワーカープロセスを有効にします。
worker_processes 4;
その場合、各ワーカープロセスが独自のカウンターを持つことになります。
設定をテストし、サーバーをリロードしてみましょう。
openresty -p $PWD/ -t
kill -HUP `cat logs/nginx.pid`
これで 4 つのワーカープロセスが動作しているはずです。
ps aux|grep nginx|grep -v tmp
したがって、この Lua モジュールによるデータ共有方法は、主に Lua レベルのデータキャッシングに使用されます。
OpenResty に付属の resty.lrucache Lua
モジュールは、このようなシナリオのために設計されています。
restydoc resty.lrucache
このモジュールについては、後のチュートリアルで説明します。
すべてのワーカープロセス間でデータを共有したい場合は、代わりに Lua 共有メモリディクショナリを使用する必要があります。
restydoc -s lua_shared_dict
restydoc -s ngx.shared.DICT
この話題については、別の専用チュートリアルで取り上げます。
著者について
章亦春(Zhang Yichun)は、オープンソースの OpenResty® プロジェクトの創始者であり、OpenResty Inc. の CEO および創業者です。
章亦春(GitHub ID: agentzh)は中国江蘇省生まれで、現在は米国ベイエリアに在住しております。彼は中国における初期のオープンソース技術と文化の提唱者およびリーダーの一人であり、Cloudflare、Yahoo!、Alibaba など、国際的に有名なハイテク企業に勤務した経験があります。「エッジコンピューティング」、「動的トレーシング」、「機械プログラミング」 の先駆者であり、22 年以上のプログラミング経験と 16 年以上のオープンソース経験を持っております。世界中で 4000 万以上のドメイン名を持つユーザーを抱えるオープンソースプロジェクトのリーダーとして、彼は OpenResty® オープンソースプロジェクトをベースに、米国シリコンバレーの中心部にハイテク企業 OpenResty Inc. を設立いたしました。同社の主力製品である OpenResty XRay動的トレーシング技術を利用した非侵襲的な障害分析および排除ツール)と OpenResty XRay(マイクロサービスおよび分散トラフィックに最適化された多機能
翻訳
英語版の原文と日本語訳版(本文)をご用意しております。読者の皆様による他の言語への翻訳版も歓迎いたします。全文翻訳で省略がなければ、採用を検討させていただきます。心より感謝申し上げます!