ngx_http_lua_module - 將 Lua 的功能嵌入到 Nginx HTTP 伺服器中。
該模組是OpenResty的核心元件。如果您正在使用這個模組,那麼您本質上就是在使用 OpenResty :)
此模組不隨 Nginx 來源一起分發。請參閱安裝說明。
生產準備就緒。
本文檔描述了 ngx_lua v0.10.25,該版本於 2023 年 6 月 19 日發布。
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”)。本文檔交替使用術語“Lua”和“LuaJIT”來指 LuaJIT 解釋器。
透過利用 Nginx 的子請求,該模組允許將強大的 Lua 線程(稱為 Lua「協程」)整合到 Nginx 事件模型中。
與 Apache 的 mod_lua 和 Lighttpd 的 mod_magnet 不同,只要使用該模組提供的 Nginx API for Lua 來處理對 MySQL、PostgreSQL、Memcached 等上游服務的請求,使用該模組執行的 Lua 程式碼就可以在網路流量上100% 無阻塞、Redis 或上游 HTTP Web 服務。
此模組至少可以使用以下 Lua 函式庫和 Nginx 模組:
幾乎任何 Nginx 模組都可以透過 ngx.location.capture 或 ngx.location.capture_multi 與此 ngx_lua 模組一起使用,但建議使用這些lua-resty-*
庫,而不是建立子請求來存取 Nginx 上游模組,因為前者通常更加靈活且記憶體效率更高。
Lua 解釋器(也稱為「Lua State」或「LuaJIT VM 實例」)在單一 Nginx 工作進程中的所有請求之間共享,以最大限度地減少記憶體使用。請求上下文使用輕量級 Lua 協程進行隔離。
載入的 Lua 模組會保留在 Nginx 工作進程層級中,導致即使在重負載下,Lua 中的記憶體佔用也很小。
此模組插入 Nginx 的「http」子系統中,因此它只能使用 HTTP 系列中的下游通訊協定(HTTP 0.9/1.0/1.1/2.0、WebSockets 等)。如果你想與下游客戶端進行通用 TCP 通信,那麼你應該使用 ngx_stream_lua 模組,它提供了相容的 Lua API。
回目錄
僅舉幾例:
可能性是無限的,因為該模組允許將 Nginx 中的各種元素組合在一起,並向使用者展示 Lua 語言的強大功能。本模組提供了腳本編寫的充分靈活性,同時藉助 LuaJIT 2.x 在 CPU 時間和記憶體佔用方面提供與本機 C 語言程式相當的效能等級。
其他腳本語言實作通常很難達到這個效能水準。
回目錄
該模組的最新版本與以下版本的 Nginx 相容:
不支援 1.6.0(不包括)之前的 Nginx 核心。
回目錄
強烈建議使用 OpenResty 版本,它捆綁了 Nginx、ngx_lua(此模組)、LuaJIT 以及其他強大的配套 Nginx 模組和 Lua 庫。
不鼓勵您自己使用 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-dynamic-module=PATH
選項而不是--add-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
版本中引入。要啟用這些巨集中的一個或多個,只需將額外的 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 協定不支援分塊輸出,且當回應主體不為空時需要明確Content-Length
標頭以支援 HTTP 1.0 keep-alive。因此,當發出 HTTP 1.0 請求並on
lua_http10_buffering 指令時,ngx_lua 將緩衝 ngx.say 和 ngx.print 呼叫的輸出,並延遲發送回應標頭,直到收到所有回應正文輸出。此時ngx_lua就可以計算出body的總長度,並建構一個適當的Content-Length
頭回傳給HTTP 1.0客戶端。然而,如果在執行的 Lua 程式碼中設定了Content-Length
回應頭,即使 lua_http10_buffering 指令on
則該緩衝也將被停用。
對於大型流輸出回應,停用 lua_http10_buffering 指令以最大限度地減少記憶體使用非常重要。
請注意,常見的 HTTP 基準測試工具(例如ab
和http_load
預設發出 HTTP 1.0 請求。若要強制curl
發送HTTP 1.0請求,請使用-0
選項。
回目錄
使用 LuaJIT 2.x,可以將純 Lua 模組的字節碼靜態連結到 Nginx 執行檔。
您可以使用luajit
可執行文件將.lua
Lua 模組文件編譯為包含導出的字節碼數據的.o
目標文件,然後直接在 Nginx 構建中鏈接.o
文件。
下面是一個簡單的例子來證明這一點。假設我們有以下名為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 調試信息,你可以指定上面的-b
選項而不是-bg
。
然後在建構 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 ()
而這段程式碼不再依賴外部的foo.lua
文件,因為它已經被編譯成nginx
可執行檔了。
如果你想在呼叫require
時在 Lua 模組名稱中使用點,如下所示
local foo = require " resty.foo "
那麼您需要將foo.lua
檔案重新命名為resty_foo.lua
然後使用luajit
命令列實用程式將其編譯為.o
檔案。
將.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
文件,那麼在單一命令中命名它們可能是不可行的。在這種情況下,您可以為.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 模組僅加載一次,並且所有協程將共享該模組的相同副本(其程式碼和資料)。
請注意,強烈建議不要使用全域 Lua 變量,因為它可能會導致並發請求之間出現意外的競爭情況。
下面是透過 Lua 模組在 Nginx Worker 中共享資料的小範例:
-- 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 master 下有多個 Nginx Worker 程序時,資料共享不能跨越這些 Worker 之間的進程邊界。
通常建議以這種方式共享唯讀資料。只要計算過程中沒有非阻塞 I/O 操作(包括 ngx.sleep),您也可以在每個 Nginx 工作進程的所有並發請求之間共用可變更的資料。只要您不將控制權交還給 Nginx 事件循環和 ngx_lua 的輕量級執行緒調度程式(即使是隱式的),兩者之間就永遠不會出現任何競爭條件。因此,當您想要在工作執行緒層級共享可變更的資料時,請務必非常小心。有缺陷的最佳化很容易導致負載下難以調試的競爭條件。
如果需要伺服器範圍內的資料共享,則使用下列一種或多種方法:
memcached
、 redis
、 MySQL
或PostgreSQL
。 OpenResty 官方版本附帶了一組配套的 Nginx 模組和 Lua 庫,它們提供了與這些資料儲存機制的介面。回目錄
回目錄
儘管連線失敗(例如出現Connection Refused
錯誤),tcpsock:connect 方法仍可能指示success
。
但是,稍後操作 cosocket 物件的嘗試將會失敗,並傳回由失敗的連線操作所產生的實際錯誤狀態訊息。
此問題是由於 Nginx 事件模型的限製造成的,並且似乎僅影響 Mac OS X。
回目錄
dofile
和require
內建函數目前在 LuaJIT 2.0/2.1 中被實作為 C 函數,因此如果dofile
或require
載入的Lua 檔案呼叫了ngx.location.capture*、ngx.exec、ngx.exit 或其他需要yield 的API 函數在 Lua 檔案的頂層範圍內,則會引發 Lua 錯誤「嘗試跨越 C 呼叫邊界」。為了避免這種情況,請將這些需要yield的呼叫放入Lua檔案中您自己的Lua函數中,而不是檔案的頂級範圍。回目錄
導入模組時必須小心,應該使用這種形式:
local xxx = require ( ' xxx ' )
而非舊的已棄用的形式:
require ( ' xxx ' )
原因如下:根據設計,全域環境與與其關聯的 Nginx 請求處理程序具有完全相同的生命週期。每個請求處理程序都有自己的一組 Lua 全域變量,這就是請求隔離的想法。 Lua 模組實際上是由第一個 Nginx 請求處理程序加載的,並由內置的require()
緩存在package.loaded
表中以供以後參考,並且某些 Lua 模組使用的內置module()
具有設置的副作用載入模組表的全域變數。但是這個全域變數將在請求處理程序結束時被清除,並且每個後續請求處理程序都有自己的(乾淨的)全域環境。因此,存取nil
值時會出現 Lua 異常。
在 ngx_lua 上下文中通常不建議使用 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 Worker 內的資料共享。
回目錄
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。
cosockets 目前也在 init_by_lua* 和 init_worker_by_lua* 指令上下文中停用,但我們將來可能會添加對這些上下文的支持,因為 Nginx 核心沒有限制(或者可以解決該限制)。
但是,當原始上下文不需要等待 cosocket 結果時,存在一種解決方法。也就是說,透過 ngx.timer.at API 建立一個零延遲計時器,並在計時器處理程序中執行 cosocket 結果,該處理程序與創建計時器的原始上下文非同步運行。
回目錄
注意在v0.9.17
版本之後,可以使用*_by_lua_block {}
配置指令來避免此陷阱。
PCRE 序列(如d
、 s
或w
)需要特別注意,因為在字串文字中,反斜線字符會在處理之前被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!"
為了避免這種情況,請雙重轉義反斜線:
# 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 設定檔解析器只需轉義一次反斜線。
# 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"
這裡,Nginx 設定檔解析器將[[\d+]]
剝離為[[d+]]
,並且處理正確。
請注意,如果正規表示式模式包含[...]
序列,則可能需要更長的長括號[=[...]=]
。如果需要,可以使用[=[...]=]
形式作為預設形式。
# 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 語言解析器只會刪除反斜杠,因此每個反斜杠只需轉義一次。
-- 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 尚不能在 Nginx 的 SPDY 模式下運作:ngx.location.capture、ngx.location.capture_multi 和 ngx.req.socket。
回目錄
Nginx 可以(至少)提前終止請求:
這意味著通常運行的階段將被跳過,例如重寫或存取階段。這也意味著無論如何運行的後續階段(例如 log_by_lua)將無法存取通常在這些階段中設定的資訊。
回目錄
bsdrecv
方法。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 模組:
在配置過程中新增這些模組的順序很重要,因為過濾鏈中任何過濾器模組的位置都決定了最終的輸出。正確的新增順序如上所示。
3rd 方 Lua 庫:
應用: