ngx_http_lua_module - Lua の機能を Nginx HTTP サーバーに組み込みます。
このモジュールは OpenResty のコアコンポーネントです。このモジュールを使用している場合は、基本的に OpenResty を使用していることになります:)
このモジュールは、Nginx ソースと一緒には配布されません。インストール手順を参照してください。
生産準備完了。
このドキュメントでは、2023 年 6 月 19 日にリリースされた ngx_lua v0.10.25 について説明します。
YouTube ビデオ「OpenResty/Lua を使用した Hello World HTTP の例」
YouTube ビデオ「OpenResty/Nginx アプリケーションで独自の Lua モジュールを作成する」
YouTubeビデオ「OpenRestyのrestyコマンドラインユーティリティデモ」
YouTube ビデオ「OpenResty で Lua コードの実行時間を正しく測定する」
YouTube ビデオ「Lua モジュールを LuaJIT バイトコードにプリコンパイルして OpenResty の起動を高速化する」
弊社の公式 YouTube チャンネル OpenResty をぜひご購読ください。
目次に戻る
# set search paths for pure Lua external libraries (';;' is the default path):
lua_package_path '/foo/bar/?.lua;/blah/?.lua;;' ;
# set search paths for Lua external libraries written in C (can also use ';;'):
lua_package_cpath '/bar/baz/?.so;/blah/blah/?.so;;' ;
server {
location /lua_content {
# MIME type determined by default_type:
default_type 'text/plain' ;
content_by_lua_block {
ngx.say('Hello,world!')
}
}
location /nginx_var {
# MIME type determined by default_type:
default_type 'text/plain' ;
# try access /nginx_var?a=hello,world
content_by_lua_block {
ngx.say(ngx.var.arg_a)
}
}
location = /request_body {
client_max_body_size 50k ;
client_body_buffer_size 50k ;
content_by_lua_block {
ngx.req.read_body() -- explicitly read the req body
local data = ngx.req.get_body_data()
if data then
ngx.say(" body data: ")
ngx.print(data)
return
end
-- body may get buffered in a temp file:
local file = ngx.req.get_body_file()
if file then
ngx.say(" body is in file ", file)
else
ngx.say(" no body found ")
end
}
}
# transparent non-blocking I/O in Lua via subrequests
# (well, a better way is to use cosockets)
location = /lua {
# MIME type determined by default_type:
default_type 'text/plain';
content_by_lua_block {
local res = ngx.location.capture(" /some_other_location ")
if res then
ngx.say(" status: ", res.status)
ngx.say(" body: ")
ngx.print(res.body)
end
}
}
location = /foo {
rewrite_by_lua_block {
res = ngx.location.capture(" /memc ",
{ args = { cmd = " incr ", key = ngx.var.uri } }
)
}
proxy_pass http://blah.blah.com;
}
location = /mixed {
rewrite_by_lua_file /path/to/rewrite.lua;
access_by_lua_file /path/to/access.lua;
content_by_lua_file /path/to/content.lua;
}
# use nginx var in code path
# CAUTION: contents in nginx var must be carefully filtered,
# otherwise there'll be great security risk!
location ~ ^/app/([-_a-zA-Z0-9/]+) {
set $path $1 ;
content_by_lua_file /path/to/lua/app/root/ $path .lua;
}
location / {
client_max_body_size 100k;
client_body_buffer_size 100k;
access_by_lua_block {
-- check the client IP address is in our black list
if ngx.var.remote_addr == " 132.5.72.3 " then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
-- check if the URI contains bad words
if ngx.var.uri and
string.match(ngx.var.request_body, " evil ")
then
return ngx.redirect(" /terms_of_use.html ")
end
-- tests passed
}
# proxy_pass/fastcgi_pass/etc settings
}
}
目次に戻る
このモジュールは、LuaJIT 2.0/2.1 を Nginx に組み込みます。これは OpenResty のコアコンポーネントです。このモジュールを使用している場合は、基本的に OpenResty を使用していることになります。
このモジュールのバージョンv0.10.16
以降、標準 Lua インタープリター (「PUC-Rio Lua」とも呼ばれます) はサポートされなくなりました。このドキュメントでは、LuaJIT インタープリターを指すために「Lua」と「LuaJIT」という用語を同じ意味で使用します。
このモジュールは、Nginx のサブリクエストを活用することで、強力な Lua スレッド (Lua「コルーチン」として知られる) を Nginx イベント モデルに統合することができます。
Apache の mod_lua や Lighttpd の mod_magnet とは異なり、このモジュールを使用して実行される Lua コードは、このモジュールによって提供される Lua 用の Nginx API が MySQL、PostgreSQL、Memcached などのアップストリーム サービスへのリクエストを処理するために使用される限り、ネットワーク トラフィックを100% ノンブロッキングにすることができます。 、Redis、またはアップストリーム HTTP Web サービス。
このモジュールでは、少なくとも次の Lua ライブラリと Nginx モジュールを使用できます。
ngx.location.capture または ngx.location.capture_multi を使用して、ほとんどすべての Nginx モジュールをこの ngx_lua モジュールで使用できますが、Nginx アップストリーム モジュールにアクセスするためのサブリクエストを作成する代わりに、これらのlua-resty-*
ライブラリを使用することをお勧めします。通常、前者の方がはるかに柔軟でメモリ効率が高くなります。
Lua インタープリター (「Lua ステート」または「LuaJIT VM インスタンス」とも呼ばれます) は、メモリ使用量を最小限に抑えるために、単一の Nginx ワーカー プロセス内のすべてのリクエストで共有されます。リクエスト コンテキストは、軽量の Lua コルーチンを使用して分離されます。
ロードされた Lua モジュールは Nginx ワーカー プロセス レベルに保持され、高負荷時でも Lua のメモリ フットプリントが小さくなります。
このモジュールは Nginx の「http」サブシステムに接続されているため、HTTP ファミリのダウンストリーム通信プロトコル (HTTP 0.9/1.0/1.1/2.0、WebSocket など) のみを通信できます。ダウンストリーム クライアントとの汎用 TCP 通信を行う場合は、代わりに、互換性のある Lua API を提供する ngx_stream_lua モジュールを使用する必要があります。
目次に戻る
いくつか例を挙げると、
このモジュールにより、Nginx 内のさまざまな要素を統合し、Lua 言語のパワーをユーザーに公開できるため、可能性は無限です。このモジュールは、LuaJIT 2.x のおかげで、CPU 時間とメモリ使用量の両方の点でネイティブ C 言語プログラムに匹敵するパフォーマンス レベルを提供しながら、スクリプト作成の完全な柔軟性を提供します。
他のスクリプト言語実装は通常、このパフォーマンス レベルに匹敵するのに苦労します。
目次に戻る
このモジュールの最新バージョンは、次のバージョンの Nginx と互換性があります。
1.6.0 (限定) より古い Nginx コアはサポートされていません。
目次に戻る
Nginx、ngx_lua (このモジュール)、LuaJIT、および他の強力なコンパニオン Nginx モジュールと Lua ライブラリをバンドルする OpenResty リリースを使用することを強くお勧めします。
正確に正しく設定するのは難しいため、Nginx を使用してこのモジュールを自分で構築することはお勧めできません。
Nginx、LuaJIT、および OpenSSL の公式リリースにはさまざまな制限と長年のバグがあり、このモジュールの機能の一部が無効になったり、正しく動作しなかったり、動作が遅くなる可能性があることに注意してください。 OpenResty の公式リリースには、OpenResty の最適化された LuaJIT 2.1 フォークと Nginx/OpenSSL パッチがバンドルされているため、これらのリリースをお勧めします。
あるいは、ngx_lua を手動で Nginx にコンパイルすることもできます。
このモジュールを使用してソースをビルドします。
wget ' https://openresty.org/download/nginx-1.19.3.tar.gz '
tar -xzvf nginx-1.19.3.tar.gz
cd nginx-1.19.3/
# tell nginx's build system where to find LuaJIT 2.0:
export LUAJIT_LIB=/path/to/luajit/lib
export LUAJIT_INC=/path/to/luajit/include/luajit-2.0
# tell nginx's build system where to find LuaJIT 2.1:
export LUAJIT_LIB=/path/to/luajit/lib
export LUAJIT_INC=/path/to/luajit/include/luajit-2.1
# Here we assume Nginx is to be installed under /opt/nginx/.
./configure --prefix=/opt/nginx
--with-ld-opt= " -Wl,-rpath,/path/to/luajit/lib "
--add-module=/path/to/ngx_devel_kit
--add-module=/path/to/lua-nginx-module
# Note that you may also want to add `./configure` options which are used in your
# current nginx build.
# You can get usually those options using command nginx -V
# you can change the parallelism number 2 below to fit the number of spare CPU cores in your
# machine.
make -j2
make install
# Note that this version of lug-nginx-module not allow to set `lua_load_resty_core off;` any more.
# So, you have to install `lua-resty-core` and `lua-resty-lrucache` manually as below.
cd lua-resty-core
make install PREFIX=/opt/nginx
cd lua-resty-lrucache
make install PREFIX=/opt/nginx
# add necessary `lua_package_path` directive to `nginx.conf`, in the http context
lua_package_path " /opt/nginx/lib/lua/?.lua;; " ;
目次に戻る
NGINX 1.9.11 以降では、上記の./configure
コマンド ラインで--add-module=PATH
の代わりに--add-dynamic-module=PATH
オプションを使用して、このモジュールを動的モジュールとしてコンパイルすることもできます。次に、load_module ディレクティブを介してnginx.conf
にモジュールを明示的にロードできます。たとえば、次のようになります。
load_module /path/to/modules/ndk_http_module.so; # assuming NDK is built as a dynamic module too
load_module /path/to/modules/ngx_http_lua_module.so;
目次に戻る
OpenResty または Nginx コアを使用してこのモジュールを構築する際、C コンパイラ オプションを介して次の C マクロを定義できます。
NGX_LUA_USE_ASSERT
定義すると、ngx_lua C コード ベースでアサーションが有効になります。ビルドのデバッグまたはテストに推奨されます。有効にすると、実行時に多少の (わずかな) オーバーヘッドが発生する可能性があります。このマクロは、 v0.9.10
リリースで初めて導入されました。NGX_LUA_ABORT_AT_PANIC
LuaJIT VM がパニックになると、ngx_lua は現在の nginx ワーカー プロセスにデフォルトで正常に終了するように指示します。この C マクロを指定すると、ngx_lua は現在の nginx ワーカー プロセス (通常はコア ダンプ ファイルが生成されます) を直ちに中止します。このオプションは、VM パニックのデバッグに役立ちます。このオプションは、 v0.9.8
リリースで初めて導入されました。これらのマクロの 1 つ以上を有効にするには、追加の C コンパイラ オプションを Nginx または OpenResty の./configure
スクリプトに渡すだけです。例えば、
./configure --with-cc-opt="-DNGX_LUA_USE_ASSERT -DNGX_LUA_ABORT_AT_PANIC"
目次に戻る
目次に戻る
openresty-en メーリング リストは英語話者向けです。
目次に戻る
openresty メーリング リストは中国語話者向けです。
目次に戻る
このプロジェクトのコード リポジトリは、GitHub の openresty/lua-nginx-module でホストされています。
目次に戻る
バグレポート、ウィッシュリスト、またはパッチを次の方法で送信してください。
目次に戻る
YouTube ビデオ「OpenResty で Lua コードの実行時間を正しく測定する」を見る
v0.5.0rc32
リリース以降、すべての*_by_lua_file
設定ディレクティブ (content_by_lua_file など) は、LuaJIT 2.0/2.1 の生のバイトコード ファイルの直接ロードをサポートしています。
/path/to/luajit/bin/luajit -b /path/to/input_file.lua /path/to/output_file.ljbc
-bg
オプションを使用すると、LuaJIT バイトコード ファイルにデバッグ情報を含めることができます。
/path/to/luajit/bin/luajit -bg /path/to/input_file.lua /path/to/output_file.ljbc
詳細については、 -b
オプションに関する公式 LuaJIT ドキュメントを参照してください。
https://luajit.org/running.html#opt_b
LuaJIT 2.1 によって生成されたバイトコード ファイルは LuaJIT 2.0 と互換性がなく、またその逆も同様であることに注意してください。 LuaJIT 2.1 バイトコードのサポートは、ngx_lua v0.9.3 で初めて追加されました。
標準 Lua 5.1 バイトコード ファイルを LuaJIT 2.0/2.1 にリンクされた ngx_lua インスタンスにロードしようとすると (またはその逆)、次のような Nginx エラー メッセージが表示されます。
[error] 13909#0: *1 failed to load Lua inlined code: bad byte-code header in /path/to/test_file.luac
require
やdofile
などの Lua プリミティブを介したバイトコード ファイルのロードは、常に期待どおりに機能するはずです。
目次に戻る
標準 Lua API os.getenv を介して Lua のシステム環境変数 ( foo
など) にアクセスしたい場合は、 env ディレクティブを介してnginx.conf
ファイルにこの環境変数名をリストする必要もあります。例えば、
env foo;
目次に戻る
HTTP 1.0 プロトコルはチャンク出力をサポートしておらず、HTTP 1.0 キープアライブをサポートするには、応答本文が空でない場合に明示的なContent-Length
ヘッダーが必要です。そのため、HTTP 1.0 リクエストが行われ、lua_http10_buffering ディレクティブがon
なっている場合、ngx_lua は ngx.say および ngx.print 呼び出しの出力をバッファリングし、すべての応答本文の出力が受信されるまで応答ヘッダーの送信を延期します。その時点で、ngx_lua は本文の全長を計算し、適切なContent-Length
ヘッダーを構築して HTTP 1.0 クライアントに返すことができます。ただし、 Content-Length
応答ヘッダーが実行中の Lua コードに設定されている場合、lua_http10_buffering ディレクティブがon
なっている場合でも、このバッファリングは無効になります。
大規模なストリーミング出力応答の場合は、lua_http10_buffering ディレクティブを無効にしてメモリ使用量を最小限に抑えることが重要です。
ab
やhttp_load
などの一般的な HTTP ベンチマーク ツールは、デフォルトで HTTP 1.0 リクエストを発行することに注意してください。 curl
HTTP 1.0 リクエストを送信させるには、 -0
オプションを使用します。
目次に戻る
LuaJIT 2.x を使用すると、純粋な Lua モジュールのバイトコードを Nginx 実行可能ファイルに静的にリンクできます。
luajit
実行可能ファイルを使用して、 .lua
Lua モジュール ファイルを、エクスポートされたバイトコード データを含む.o
オブジェクト ファイルにコンパイルし、その.o
ファイルを Nginx ビルドに直接リンクできます。
以下はこれを示す簡単な例です。 foo.lua
という名前の次の.lua
ファイルがあるとします。
-- foo.lua
local _M = {}
function _M . go ()
print ( " Hello from foo " )
end
return _M
次に、この.lua
ファイルをfoo.o
ファイルにコンパイルします。
/path/to/luajit/bin/luajit -bg foo.lua foo.o
ここで重要なのは、 .lua
ファイルの名前です。これにより、後でこのモジュールを Lua ランドでどのように使用するかが決まります。ファイル名foo.o
.o
ファイル拡張子 (どの出力形式が使用されているかをluajit
知らせます) を除いてまったく重要ではありません。結果のバイトコードから Lua デバッグ情報を取り除きたい場合は、 -bg
の代わりに上記の-b
オプションを指定するだけです。
次に、Nginx または OpenResty をビルドするときに、 --with-ld-opt="foo.o"
オプションを./configure
スクリプトに渡します。
./configure --with-ld-opt= " /path/to/foo.o " ...
最後に、ngx_lua によって実行される Lua コードで次の操作を行うだけです。
local foo = require " foo "
foo . go ()
また、このコード部分は、すでにnginx
実行可能ファイルにコンパイルされているため、外部のfoo.lua
ファイルには依存しなくなりました。
require
呼び出すときに Lua モジュール名にドットを使用したい場合は、次のようにします。
local foo = require " resty.foo "
次に、 luajit
コマンドライン ユーティリティを使用して.o
ファイルにコンパイルする前に、 foo.lua
ファイルの名前をresty_foo.lua
に変更する必要があります。
.lua
ファイルを.o
ファイルにコンパイルするときは、nginx + ngx_lua をビルドするときとまったく同じバージョンの LuaJIT を使用することが重要です。これは、LuaJIT バイトコード形式が異なる LuaJIT バージョン間で互換性がない可能性があるためです。バイトコード形式に互換性がない場合、Lua モジュールが見つからないという Lua ランタイム エラーが表示されます。
コンパイルおよびリンクする.lua
ファイルが複数ある場合は、 --with-ld-opt
オプションの値でそれらの.o
ファイルを同時に指定するだけです。例えば、
./configure --with-ld-opt= " /path/to/foo.o /path/to/bar.o " ...
.o
ファイルが多すぎる場合は、1 つのコマンドですべてに名前を付けるのが現実的ではない可能性があります。この場合、次のように.o
ファイルの静的ライブラリ (またはアーカイブ) を構築できます。
ar rcus libmyluafiles.a * .o
次に、 myluafiles
アーカイブ全体を nginx 実行可能ファイルにリンクできます。
./configure
--with-ld-opt= " -L/path/to/lib -Wl,--whole-archive -lmyluafiles -Wl,--no-whole-archive "
ここで、 /path/to/lib
libmyluafiles.a
ファイルを含むディレクトリのパスです。ここではリンカー オプション--whole-archive
が必要であることに注意してください。そうしないと、アーカイブ内のシンボルが nginx 実行可能ファイルの主要部分で言及されていないため、アーカイブがスキップされます。
目次に戻る
同じ Nginx ワーカー プロセスによって処理されるすべてのリクエスト間でデータをグローバルに共有するには、共有データを Lua モジュールにカプセル化し、Lua require
ビルトインを使用してモジュールをインポートし、Lua で共有データを操作します。これが機能するのは、必要な Lua モジュールが 1 回だけロードされ、すべてのコルーチンがモジュールの同じコピー (コードとデータの両方) を共有するためです。
グローバル Lua 変数の使用は、同時リクエスト間で予期しない競合状態を引き起こす可能性があるため、使用しないことを強くお勧めします。
Lua モジュールを介して Nginx ワーカー内でデータを共有する小さな例を次に示します。
-- mydata.lua
local _M = {}
local data = {
dog = 3 ,
cat = 4 ,
pig = 5 ,
}
function _M . get_age ( name )
return data [ name ]
end
return _M
そしてnginx.conf
からアクセスします。
location /lua {
content_by_lua_block {
local mydata = require "mydata"
ngx.say(mydata.get_age("dog"))
}
}
この例のmydata
モジュールは、 /lua
場所への最初のリクエストでのみロードされて実行され、同じ Nginx ワーカー プロセスへの後続のすべてのリクエストでは、モジュールの再ロードされたインスタンスと、同じデータのコピーが使用されます。 HUP
シグナルが Nginx マスター プロセスに送信されてリロードが強制されるまで、それが続きます。このデータ共有手法は、このモジュールに基づく高性能 Lua アプリケーションに不可欠です。
このデータ共有は、サーバーごとではなく、ワーカーごとに行われることに注意してください。つまり、Nginx マスターの下に複数の Nginx ワーカー プロセスがある場合、データ共有はこれらのワーカー間のプロセス境界を越えることはできません。
通常は、この方法で読み取り専用データを共有することをお勧めします。計算中にノンブロッキング I/O 操作 (ngx.sleep を含む) がない限り、各 Nginx ワーカー プロセスのすべての同時リクエスト間で変更可能なデータを共有することもできます。 Nginx イベント ループと ngx_lua のライト スレッド スケジューラに (暗黙的であっても) 制御を戻さない限り、その間に競合状態が発生することはありません。このため、変更可能なデータをワーカー レベルで共有する場合は、常に細心の注意を払ってください。バグの多い最適化は、負荷がかかるとデバッグが困難な競合状態を簡単に引き起こす可能性があります。
サーバー全体のデータ共有が必要な場合は、次のアプローチの 1 つ以上を使用します。
memcached
、 redis
、 MySQL
、 PostgreSQL
などのデータ ストレージ メカニズムを使用します。 OpenResty 公式リリースには、これらのデータ ストレージ メカニズムとのインターフェイスを提供する一連のコンパニオン Nginx モジュールと Lua ライブラリが付属しています。目次に戻る
目次に戻る
tcpsock:connect メソッドは、 Connection Refused
エラーなどの接続失敗にもかかわらずsuccess
示す場合があります。
ただし、後で cosocket オブジェクトを操作しようとすると失敗し、失敗した接続操作によって生成された実際のエラー ステータス メッセージが返されます。
この問題は Nginx イベント モデルの制限が原因であり、Mac OS X にのみ影響すると思われます。
目次に戻る
dofile
およびrequire
ビルトインは現在、LuaJIT 2.0/2.1 の C 関数として実装されているため、 dofile
またはrequire
によってロードされる Lua ファイルが ngx.location.capture*、ngx.exec、ngx.exit、または生成を必要とするその他の API 関数を呼び出す場合、 Lua ファイルの最上位スコープにある場合、Lua エラー「C 呼び出し境界を越えて譲歩しようとしています」が発生します。これを回避するには、ファイルのトップレベルのスコープではなく、Lua ファイル内の独自の Lua 関数に、yield を必要とする呼び出しを記述します。目次に戻る
モジュールをインポートするときは注意が必要で、次の形式を使用する必要があります。
local xxx = require ( ' xxx ' )
古い非推奨の形式の代わりに:
require ( ' xxx ' )
その理由は次のとおりです。設計により、グローバル環境の存続期間は、それに関連付けられた Nginx リクエスト ハンドラーとまったく同じです。各リクエスト ハンドラーには独自の Lua グローバル変数セットがあり、これがリクエスト分離の考え方です。 Lua モジュールは実際には最初の Nginx リクエスト ハンドラーによってロードされ、後で参照できるようにpackage.loaded
テーブルのrequire()
ビルトインによってキャッシュされます。また、一部の Lua モジュールで使用されるmodule()
ビルトインには設定の副作用があります。ロードされたモジュールテーブルへのグローバル変数。ただし、このグローバル変数はリクエスト ハンドラーの終了時にクリアされ、後続のすべてのリクエスト ハンドラーはすべて独自の (クリーンな) グローバル環境を持ちます。そのため、 nil
値にアクセスすると Lua 例外が発生します。
Lua グローバル変数の使用は、ngx_lua コンテキストでは次のように一般的に推奨されません。
したがって、代わりに常に適切なローカル スコープ内で宣言することを強くお勧めします。
-- Avoid
foo = 123
-- Recommended
local foo = 123
-- Avoid
function foo () return 123 end
-- Recommended
local function foo () return 123 end
Lua コード内の Lua グローバル変数のすべてのインスタンスを検索するには、すべての.lua
ソース ファイルに対して lua-releng ツールを実行します。
$ lua-releng
Checking use of Lua global variables in file lib/foo/bar.lua ...
1 [1489] SETGLOBAL 7 -1 ; contains
55 [1506] GETGLOBAL 7 -3 ; setvar
3 [1545] GETGLOBAL 3 -4 ; varexpand
出力には、ファイルlib/foo/bar.lua
の行 1489 がcontains
という名前のグローバル変数に書き込み、行 1506 がグローバル変数setvar
から読み取り、行 1545 がグローバルvarexpand
読み取ることが示されています。
このツールは、Lua モジュール関数内のローカル変数がすべてlocal
キーワードを使用して宣言されていることを保証します。そうでない場合は、実行時例外がスローされます。このような変数にアクセスする際の望ましくない競合状態を防ぎます。この背後にある理由については、「Nginx ワーカー内のデータ共有」を参照してください。
目次に戻る
ngx.location.capture および ngx.location.capture_multi ディレクティブは、add_before_body、add_after_body、auth_request、echo_location、echo_location_async、echo_subrequest、または echo_subrequest_async ディレクティブを含む場所をキャプチャできません。
location /foo {
content_by_lua_block {
res = ngx.location.capture( "/bar" )
}
}
location /bar {
echo_location /blah;
}
location /blah {
echo "Success!" ;
}
$ curl -i http://example.com/foo
期待どおりに機能しません。
目次に戻る
Nginx コアの内部制限により、cosocket API は set_by_lua*、log_by_lua*、header_filter_by_lua*、body_filter_by_lua のコンテキストでは無効になります。
現在、cosocket は init_by_lua* および init_worker_by_lua* ディレクティブ コンテキストでも無効になっていますが、Nginx コアには制限がないため (または制限が回避される可能性があります)、将来これらのコンテキストのサポートを追加する可能性があります。
ただし、元のコンテキストがコソケットの結果を待つ必要がない場合には、回避策が存在します。つまり、ngx.timer.at API を介してゼロ遅延タイマーを作成し、タイマー ハンドラーで cosocket の結果を実行すると、タイマーを作成する元のコンテキストに対して非同期で実行されます。
目次に戻る
注意v0.9.17
リリース以降、 *_by_lua_block {}
設定ディレクティブを使用することでこの落とし穴を回避できます。
d
、 s
、 w
などの PCRE シーケンスには特別な注意が必要です。文字列リテラルでは、バックスラッシュ文字が、言語パーサー内にない場合、処理前に Lua 言語パーサーと Nginx 構成ファイル パーサーの両方によって取り除かれるためです。
*_by_lua_block {}
ディレクティブ。したがって、次のスニペットは期待どおりに機能しません。
# nginx.conf
? location /test {
? content_by_lua '
? local regex = "d+" -- THIS IS WRONG OUTSIDE OF A *_by_lua_block DIRECTIVE
? local m = ngx.re.match("hello, 1234", regex)
? if m then ngx.say(m[0]) else ngx.say("not matched!") end
? ' ;
? }
# evaluates to "not matched!"
これを回避するには、バックスラッシュを2 回エスケープします。
# nginx.conf
location /test {
content_by_lua '
local regex = "\\d+"
local m = ngx.re.match("hello, 1234", regex)
if m then ngx.say(m[0]) else ngx.say("not matched!") end
' ;
}
# evaluates to "1234"
ここで、 \\d+
Nginx 構成ファイル パーサーによって\d+
に取り除かれ、これは実行前に Lua 言語パーサーによってさらにd+
に取り除かれます。
あるいは、正規表現パターンを「長い括弧」 [[...]]
で囲むことにより、長い括弧で囲まれた Lua 文字列リテラルとして表すこともできます。この場合、バックスラッシュは Nginx 構成ファイル パーサーで 1 回だけエスケープする必要があります。
# nginx.conf
location /test {
content_by_lua '
local regex = [[\d+]]
local m = ngx.re.match("hello, 1234", regex)
if m then ngx.say(m[0]) else ngx.say("not matched!") end
' ;
}
# evaluates to "1234"
ここで、 [[\d+]]
は Nginx 構成ファイル パーサーによって[[d+]]
に取り除かれ、これは正しく処理されます。
正規表現パターンに[...]
シーケンスが含まれる場合は、長い括弧[=[...]=]
の長い from が必要になる場合があることに注意してください。必要に応じて、 [=[...]=]
フォームをデフォルトのフォームとして使用できます。
# nginx.conf
location /test {
content_by_lua '
local regex = [=[[0-9]+]=]
local m = ngx.re.match("hello, 1234", regex)
if m then ngx.say(m[0]) else ngx.say("not matched!") end
' ;
}
# evaluates to "1234"
PCRE シーケンスをエスケープする別のアプローチは、Lua コードを外部スクリプト ファイルに配置し、さまざまな*_by_lua_file
ディレクティブを使用して実行することです。このアプローチでは、バックスラッシュは Lua 言語パーサーによってのみ削除されるため、エスケープする必要があるのはそれぞれ 1 回だけです。
-- test.lua
local regex = " \ d+ "
local m = ngx . re . match ( " hello, 1234 " , regex )
if m then ngx . say ( m [ 0 ]) else ngx . say ( " not matched! " ) end
-- evaluates to "1234"
外部スクリプト ファイル内では、長い括弧で囲まれた Lua 文字列リテラルとして表示される PCRE シーケンスは変更する必要がありません。
-- test.lua
local regex = [[ d+ ]]
local m = ngx . re . match ( " hello, 1234 " , regex )
if m then ngx . say ( m [ 0 ]) else ngx . say ( " not matched! " ) end
-- evaluates to "1234"
前述したように、 *_by_lua_block {}
ディレクティブ ( v0.9.17
リリース以降で利用可能) 内にある PCRE シーケンスは変更する必要がありません。
# nginx.conf
location /test {
content_by_lua_block {
local regex = [[d+]]
local m = ngx.re.match( "hello, 1234" , regex)
if m then ngx.say(m[0]) else ngx.say( "not matched!" ) end
}
}
# evaluates to "1234"
注Lua コードが非常に長い場合は、 by_lua_file
使用することをお勧めします。
目次に戻る
同じ Nginx リクエスト内で SSI と ngx_lua を混在させることはまったくサポートされていません。 ngx_lua のみを使用してください。 SSI で実行できることはすべて ngx_lua 上で実行でき、ngx_lua を使用するとより効率的になります。
目次に戻る
ngx_lua によって提供される特定の Lua API (ngx.location.capture、ngx.location.capture_multi、および ngx.req.socket) は、Nginx の SPDY モードではまだ動作しません。
目次に戻る
Nginx は、(少なくとも) 次の方法でリクエストを早期に終了できます。
これは、再書き込みフェーズやアクセス フェーズなど、通常実行されるフェーズがスキップされることを意味します。これは、関係なく実行される後のフェーズ (log_by_lua など) が、それらのフェーズで通常設定される情報にアクセスできないことも意味します。
目次に戻る
bsdrecv
メソッドを追加するための aviramc のパッチを確認してマージします。ngx_hash_t
使用して、ngx.req.set_header などの組み込みヘッダー検索プロセスを最適化します。ignore_resp_headers
、 ignore_resp_body
、およびignore_resp
オプションを ngx.location.capture メソッドと ngx.location.capture_multi メソッドに追加します。stat
モードを追加します。目次に戻る
このモジュールの各リリースで行われた変更は、OpenResty バンドルの変更ログにリストされます。
https://openresty.org/#Changes
目次に戻る
テスト スイートを実行するには、次の依存関係が必要です。
Nginx バージョン >= 1.4.2
Perl モジュール:
Nginx モジュール:
たとえば、フィルタリング チェーン内のフィルタ モジュールの位置によって最終出力が決定されるため、構成中にこれらのモジュールを追加する順序は重要です。正しい追加順序は上に示されています。
サードパーティの Lua ライブラリ:
アプリケーション: