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 库:
应用: