前言
NGINX Resty(也称为 OpenResty)是基于 NGINX 和 LuaJIT 的高性能 Web 平台。它扩展了 NGINX 的功能,使其不仅仅是一个 HTTP 服务器,还能执行复杂的 Web 应用程序逻辑。OpenResty 在 NGINX 之上整合了 Lua 脚本引擎,通过 Lua 脚本开发者可以直接在 NGINX 中编写自定义逻辑,从而处理复杂的请求和响应流程。
主要特性:
- Lua 支持:OpenResty 最大的特点就是内置了 LuaJIT,开发者可以用 Lua 编写高性能的 Web 应用,灵活处理请求、缓存、数据库连接等。通过
ngx_lua
模块可以轻松实现复杂的请求处理逻辑。
- 高性能:OpenResty 基于 NGINX 的事件驱动架构,结合 LuaJIT 的高效执行,具备极高的并发处理能力和低延迟特性,适合处理高负载场景。
- 模块丰富:OpenResty 集成了大量常用模块,例如
lua-resty-mysql
、lua-resty-redis
等,可以方便地与数据库、缓存等外部服务进行交互。
- 内建异步支持:通过 Lua,可以使用异步非阻塞的方式处理请求,这对提高应用的性能和吞吐量非常有帮助,尤其是在与外部系统进行 I/O 操作时(如数据库、文件系统)。
- 动态配置和脚本化:相比 NGINX 静态配置,OpenResty 允许通过 Lua 脚本实现动态配置和请求处理逻辑,可以根据具体的请求参数或上下文动态生成响应。
- 轻松扩展:OpenResty 提供了强大的扩展能力,可以根据业务需求开发自定义模块或功能,同时也可以轻松与已有的 NGINX 模块结合使用。
典型应用场景:
- 动态代理:OpenResty 可以根据请求中的信息(如请求头、URL、Cookie 等)动态调整路由和代理逻辑。
- API 网关:凭借其高性能和灵活的 Lua 脚本能力,OpenResty 常被用于构建 API 网关,通过自定义脚本实现限流、鉴权、日志记录等功能。
- 缓存:可以结合 Redis 等外部缓存服务,通过 Lua 脚本灵活控制缓存策略,减少后端系统的压力。
- 日志处理和监控:可以通过 Lua 实现复杂的日志处理和格式化逻辑,支持将日志数据发送到外部系统进行进一步处理和分析。
1 安裝下載
https://openresty.org/cn/download.html
centos
安裝基礎庫: perl 5.6.1+,
libpcre,
libssl
# ubuntu
apt-get install libpcre3-dev
apt-get install libssl-dev
apt-get install perl
apt-get install make
apt-get install build-essential
apt-get install curl
# Fedora 和 RedHat 用户
yum install -y pcre-devel
yum install -y openssl-devel
yum install -y gcc
yum install -y curl
yum install -y zlib-devel
原创:有勇气的牛排
https://www.couragesteak.com/article/472
準備文件
cd /usr/local
mkdir openresty
tar -zxvf openresty-1.25.3.2.tar.gz
cd openresty-1.25.3.2
構建
cd /usr/local/openresty/openresty-1.25.3.2
./configure --prefix=/usr/local/openresty/openresty_install \
--with-luajit \
--with-http_iconv_module \
--with-stream \
--with-stream_ssl_module
# --with-luajit: 启用 LuaJIT 以支持高性能 Lua 脚本执行。
# --with-stream/--with-stream_ssl_module: 启用 Nginx 的 Stream 模块,以支持 TCP/UDP 负载均衡和处理。
# -- with-http_iconv_module: 处理多语言网站、旧系统兼容性:UTF-8、ISO-8859-1、GBK
安裝編譯
make && make install
cd /usr/local/openresty/openresty_install
启动
启动 start_openresty.sh
#!/bin/bash
# OpenResty 安装路径
OPENRESTY_PATH="/usr/local/openresty/openresty_install/nginx"
# 启动 OpenResty
$OPENRESTY_PATH/sbin/nginx
# 检查是否成功启动
if [ $? -eq 0 ]; then
echo "OpenResty 启动成功."
else
echo "OpenResty 启动失败."
fi
关闭: stop_openresty.sh
#!/bin/bash
# OpenResty 安装路径
OPENRESTY_PATH="/usr/local/openresty/openresty_install/nginx"
# 关闭 OpenResty
$OPENRESTY_PATH/sbin/nginx -s stop
# 检查是否成功关闭
if [ $? -eq 0 ]; then
echo "OpenResty 关闭成功."
else
echo "OpenResty 关闭失败."
fi
重载: reload_openresty.sh
#!/bin/bash
# OpenResty 安装路径
OPENRESTY_PATH="/usr/local/openresty/openresty_install/nginx"
# 重载 OpenResty 配置
$OPENRESTY_PATH/sbin/nginx -s reload
# 检查是否成功重载
if [ $? -eq 0 ]; then
echo "OpenResty 配置重载成功."
else
echo "OpenResty 配置重载失败."
fi
chmod +x start_openresty.sh
chmod +x stop_openresty.sh
chmod +x reload_openresty.sh
访问:
http://192.168.56.20/
基础库安装
luarocks install lua-resty-mysql
luarocks install lua-cjson
luarocks install lua-resty-http
2 HTTP方法常量
ngx.HTTP_GET
ngx.HTTP_HEAD
ngx.HTTP_PUT
ngx.HTTP_POST
ngx.HTTP_DELETE
ngx.HTTP_OPTIONS (v0.5.0rc24 版本加入)
ngx.HTTP_MKCOL (v0.8.2 版本加入)
ngx.HTTP_COPY (v0.8.2 版本加入)
ngx.HTTP_MOVE (v0.8.2 版本加入)
ngx.HTTP_PROPFIND (v0.8.2 版本加入)
ngx.HTTP_PROPPATCH (v0.8.2 版本加入)
ngx.HTTP_LOCK (v0.8.2 版本加入)
ngx.HTTP_UNLOCK (v0.8.2 版本加入)
ngx.HTTP_PATCH (v0.8.2 版本加入)
ngx.HTTP_TRACE (v0.8.2 版本加入)
3 HTTP状态常量
value = ngx.HTTP_OK (等于 200)
value = ngx.HTTP_CREATED (等于 201)
value = ngx.HTTP_SPECIAL_RESPONSE (等于 300)
value = ngx.HTTP_MOVED_PERMANENTLY (等于 301)
value = ngx.HTTP_MOVED_TEMPORARILY (等于 302)
value = ngx.HTTP_SEE_OTHER (等于 303)
value = ngx.HTTP_NOT_MODIFIED (等于 304)
value = ngx.HTTP_BAD_REQUEST (等于 400)
value = ngx.HTTP_UNAUTHORIZED (等于 401)
value = ngx.HTTP_FORBIDDEN (等于 403)
value = ngx.HTTP_NOT_FOUND (等于 404)
value = ngx.HTTP_NOT_ALLOWED (等于 405)
value = ngx.HTTP_GONE (等于 410)
value = ngx.HTTP_INTERNAL_SERVER_ERROR (等于 500)
value = ngx.HTTP_METHOD_NOT_IMPLEMENTED (等于 501)
value = ngx.HTTP_SERVICE_UNAVAILABLE (等于 503)
value = ngx.HTTP_GATEWAY_TIMEOUT (等于 504) (v0.3.1rc38 版本加入)
4 语法API
2.1 ngx.say
返回结果给客户端
语法:ngx.say("")
location / {
default_type 'text/plain';
content_by_lua_block {
ngx.say("牛逼")
}
}

2.2 ngx.print
location / {
default_type 'text/plain';
content_by_lua_block {
# 作为响应体返回
local table_data = {
'id'
}
ok, err = ngx.print(table_data)
ngx.say("有勇氣的牛排")
}
}

2.3 ngx.flush
定义:用户强制将nginx的输出缓冲区的内容,立即发送给客户端。
通常在调用 ngx.print
后使用,确保数据及时传递到客户端。
场景:
- 实时发送数据流
- 长轮训
- 分块传输编码(chunked transfer encoding)
ngx.print('...')
ngx.flush(true)
参数:
- wait:可选
- true:表示将等待数据发送完成后再继续处理
注意:
2.4 ngx.arg
2.5 ngx.var 获取nginx变量
获取值
local uri = ngx.var.uri
local uri = ngx.var.request_method
local uri = ngx.var.args
local uri = ngx.var.remote_addr
设置自定义变量值(如果nx)
ngx.var.some_variable = "new_value"
注意:
-
ngx中部分变量为只读
-
在设置变量时,如果ngx没有定义,则可能报错
2.6 ngx.log 输出日志
ngx.STDERR
ngx.EMERG
ngx.ALERT
ngx.CRIT
ngx.ERR
ngx.WARN
ngx.NOTICE
ngx.INFO
ngx.DEBUG
使用
ngx.log(ngx.ERR, '异常: ', '错误信息ERR')
ngx.log(ngx.INFO, 'IP地址: ', ngx.var.remote_addr)
ngx.log(ngx.DEBUG, 'URI地址为: ', ngx.var.uri)
输出结果在:error.log文件中

如果看不到结果,请配置
# nginx.conf 第7行左右
error_log logs/error.log debug;
2.7 ngx.ctx
location里面的全局变量/上下文变量
ngx.exit
ngx.sleep
ngx.sleep(1000)
5 请求API
arg 参数
GET 参数
http://127.0.0.1/?id=1&name=有勇气的牛排
ngx.req.get_post_args: V1.25.3.2版本已经无法使用
老方法(不知道哪个版本在用)
local args = ngx.req.get_url_args()
local id = args["id"]
lcoal age = args["name"]
ngx.say("昵称:", name)
ngx.say("ID:", id)
新语法:V1.25.3.2语法
local id = ngx.var.arg_id
local name = ngx.var.arg_name
ngx.say("昵称:", name)
ngx.say("ID:", id)
POST参数
ngx.req.get_post_args: V1.25.3.2版本已经无法使用
local id = ngx.var.arg_id
local name = ngx.var.arg_name
ngx.say("昵称:", name)
ngx.say("ID:", id)
method 方法
ngx.req.get_method()
local http_method = ngx.req.get_method()
ngx.say("方法:", http_method)

ngx.req.set_method
ngx.req.set_method(ngx.HTTP_GET)
header操作
添加、修改、清除请求头
ngx.header.content_type = 'text/plain';
ngx.header["My-Header"] = '有勇气的牛排'

重定向 跳转
ngx.redirect
注意:跳转第三方网站添加 https
http://127.0.0.1/
return ngx.redirect("/test")
return ngx.redirect("/test", 301)
return ngx.redirect("https://www.couragesteak.com/", ngx.HTTP_MOVED_TEMPORARILY)
ngx.exec
内部跳转
指令 API
init_by_lua
Master 进程被创建时执行
该指令在 nginx 重新加载配置时执行,可以将耗时的模块提前加载,或者初始化全局变量。
即:公共模块
lua_by_lua_block {
mysql = require "resty.mysql"
redis = require "resty.redis"
my_global_var = "这是一个全局变量"
}

可以导入,也可以直接写
init_worker_by_lua
每个 Worker 进程(工作进程)被创建时执行
content_by_lua
注
编译配置
[root@master openresty-1.25.3.2]# ./configure --help
--help 显示此帮助信息
--prefix=PATH 设置安装前缀目录(默认路径为 /usr/local/openresty)
--with-debug 启用调试日志记录
--with-no-pool-patch 启用 no-pool 补丁以调试内存问题
-jN 在构建 LuaJIT 2.1 时传递 -jN 选项
--without-http_echo_module 禁用 ngx_http_echo_module
--without-http_xss_module 禁用 ngx_http_xss_module
--without-http_coolkit_module 禁用 ngx_http_coolkit_module
--without-http_set_misc_module 禁用 ngx_http_set_misc_module
--without-http_form_input_module 禁用 ngx_http_form_input_module
--without-http_encrypted_session_module
禁用 ngx_http_encrypted_session_module
--without-http_srcache_module 禁用 ngx_http_srcache_module
--without-http_lua_module 禁用 ngx_http_lua_module
--without-http_lua_upstream_module 禁用 ngx_http_lua_upstream_module
--without-http_headers_more_module 禁用 ngx_http_headers_more_module
--without-http_array_var_module 禁用 ngx_http_array_var_module
--without-http_memc_module 禁用 ngx_http_memc_module
--without-http_redis2_module 禁用 ngx_http_redis2_module
--without-http_redis_module 禁用 ngx_http_redis_module
--without-http_rds_json_module 禁用 ngx_http_rds_json_module
--without-http_rds_csv_module 禁用 ngx_http_rds_csv_module
--without-stream_lua_module 禁用 ngx_stream_lua_module
--without-ngx_devel_kit_module 禁用 ngx_devel_kit_module
--without-stream 禁用 TCP/UDP 代理模块
--without-http_ssl_module 禁用 ngx_http_ssl_module
--without-stream_ssl_module 禁用 ngx_stream_ssl_module
--with-http_iconv_module 启用 ngx_http_iconv_module
--with-http_drizzle_module 启用 ngx_http_drizzle_module
--with-http_postgres_module 启用 ngx_http_postgres_module
--without-lua_cjson 禁用 lua-cjson 库
--without-lua_tablepool 禁用 lua-tablepool 库(因此也禁用 lua-resty-shell 库)
--without-lua_redis_parser 禁用 lua-redis-parser 库
--without-lua_rds_parser 禁用 lua-rds-parser 库
--without-lua_resty_dns 禁用 lua-resty-dns 库
--without-lua_resty_memcached 禁用 lua-resty-memcached 库
--without-lua_resty_redis 禁用 lua-resty-redis 库
--without-lua_resty_mysql 禁用 lua-resty-mysql 库
--without-lua_resty_upload 禁用 lua-resty-upload 库
--without-lua_resty_upstream_healthcheck
禁用 lua-resty-upstream-healthcheck 库
--without-lua_resty_string 禁用 lua-resty-string 库
--without-lua_resty_websocket 禁用 lua-resty-websocket 库
--without-lua_resty_limit_traffic 禁用 lua-resty-limit-traffic 库
--without-lua_resty_lock 禁用 lua-resty-lock 库
--without-lua_resty_lrucache 禁用 lua-resty-lrucache 库
--without-lua_resty_signal 禁用 lua-resty-signal 库(因此也禁用 lua-resty-shell 库)
--without-lua_resty_shell 禁用 lua-resty-shell 库
--without-lua_resty_core 禁用 lua-resty-core 库
--with-luajit=DIR 使用由 DIR 指定的外部 LuaJIT 2.1 安装
--with-luajit-xcflags=FLAGS 为 LuaJIT 2.1 指定额外的 C 编译器标志
--with-luajit-ldflags=FLAGS 为 LuaJIT 2.1 指定额外的 C 链接器标志
--without-luajit-lua52 禁用 LuaJIT 5.2 的扩展,以防止破坏向后兼容性
--without-luajit-gc64 禁用 LuaJIT 的 GC64 模式(在 x86_64 上默认启用)
--with-libdrizzle=DIR 指定 libdrizzle 1.0(或 drizzle)安装前缀
--with-libpq=DIR 指定 libpq(或 postgresql)安装前缀
--with-pg_config=PATH 指定 pg_config 工具的路径
Nginx 的选项继承:
--sbin-path=PATH 设置 nginx 二进制文件的路径
--modules-path=PATH 设置模块路径
--conf-path=PATH 设置 nginx.conf 文件路径
--error-log-path=PATH 设置错误日志文件路径
--pid-path=PATH 设置 nginx.pid 文件路径
--lock-path=PATH 设置 nginx.lock 文件路径
--user=USER 设置 worker 进程的非特权用户
--group=GROUP 设置 worker 进程的非特权用户组
--build=NAME 设置构建名称
--builddir=DIR 设置构建目录
--with-select_module 启用 select 模块
--without-select_module 禁用 select 模块
--with-poll_module 启用 poll 模块
--without-poll_module 禁用 poll 模块
--with-threads 启用线程池支持
--with-file-aio 启用文件 AIO 支持
--with-http_ssl_module 启用 ngx_http_ssl_module(默认启用)
--with-http_v2_module 启用 ngx_http_v2_module
--with-http_v3_module 启用 ngx_http_v3_module
--with-http_realip_module 启用 ngx_http_realip_module
--with-http_addition_module 启用 ngx_http_addition_module
--with-http_xslt_module 启用 ngx_http_xslt_module
--with-http_xslt_module=dynamic 启用动态 ngx_http_xslt_module
--with-http_image_filter_module 启用 ngx_http_image_filter_module
--with-http_image_filter_module=dynamic
启用动态 ngx_http_image_filter_module
--with-http_geoip_module 启用 ngx_http_geoip_module
--with-http_geoip_module=dynamic 启用动态 ngx_http_geoip_module
--with-http_sub_module 启用 ngx_http_sub_module
--with-http_dav_module 启用 ngx_http_dav_module
--with-http_flv_module 启用 ngx_http_flv_module
--with-http_mp4_module 启用 ngx_http_mp4_module
--with-http_gunzip_module 启用 ngx_http_gunzip_module
--with-http_gzip_static_module 启用 ngx_http_gzip_static_module
--with-http_auth_request_module 启用 ngx_http_auth_request_module
--with-http_random_index_module 启用 ngx_http_random_index_module
--with-http_secure_link_module 启用 ngx_http_secure_link_module
--with-http_degradation_module 启用 ngx_http_degradation_module
--with-http_slice_module 启用 ngx_http_slice_module
--with-http_stub_status_module 启用 ngx_http_stub_status_module
--without-http_charset_module 禁用 ngx_http_charset_module
--without-http_gzip_module 禁用 ngx_http_gzip_module
--without-http_ssi_module 禁用 ngx_http_ssi_module
--without-http_userid_module 禁用 ngx_http_userid_module
--without-http_access_module 禁用 ngx_http_access_module
--without-http_auth_basic_module 禁用 ngx_http_auth_basic_module
--without-http_mirror_module 禁用 ngx_http_mirror_module
--without-http_autoindex_module 禁用 ngx_http_autoindex_module
--without-http_geo_module 禁用 ngx_http_geo_module
--without-http_map_module 禁用 ngx_http_map_module
--without-http_split_clients_module 禁用 ngx_http_split_clients_module
--without-http_referer_module 禁用 ngx_http_referer_module
--without-http_rewrite_module 禁用 ngx_http_rewrite_module
--without-http_proxy_module 禁用 ngx_http_proxy_module
--without-http_fastcgi_module 禁用 ngx_http_fastcgi_module
--without-http_uwsgi_module 禁用 ngx_http_uwsgi_module
--without-http_scgi_module 禁用 ngx_http_scgi_module
--without-http_grpc_module 禁用 ngx_http_grpc_module
--without-http_memcached_module 禁用 ngx_http
<h2><a id="_0"></a>前言</h2>
<p>NGINX Resty(也称为 OpenResty)是基于 NGINX 和 LuaJIT 的高性能 Web 平台。它扩展了 NGINX 的功能,使其不仅仅是一个 HTTP 服务器,还能执行复杂的 Web 应用程序逻辑。OpenResty 在 NGINX 之上整合了 Lua 脚本引擎,通过 Lua 脚本开发者可以直接在 NGINX 中编写自定义逻辑,从而处理复杂的请求和响应流程。</p>
<p>主要特性:</p>
<ol>
<li><strong>Lua 支持</strong>:OpenResty 最大的特点就是内置了 LuaJIT,开发者可以用 Lua 编写高性能的 Web 应用,灵活处理请求、缓存、数据库连接等。通过 <code>ngx_lua</code> 模块可以轻松实现复杂的请求处理逻辑。</li>
<li><strong>高性能</strong>:OpenResty 基于 NGINX 的事件驱动架构,结合 LuaJIT 的高效执行,具备极高的并发处理能力和低延迟特性,适合处理高负载场景。</li>
<li><strong>模块丰富</strong>:OpenResty 集成了大量常用模块,例如 <code>lua-resty-mysql</code>、<code>lua-resty-redis</code> 等,可以方便地与数据库、缓存等外部服务进行交互。</li>
<li><strong>内建异步支持</strong>:通过 Lua,可以使用异步非阻塞的方式处理请求,这对提高应用的性能和吞吐量非常有帮助,尤其是在与外部系统进行 I/O 操作时(如数据库、文件系统)。</li>
<li><strong>动态配置和脚本化</strong>:相比 NGINX 静态配置,OpenResty 允许通过 Lua 脚本实现动态配置和请求处理逻辑,可以根据具体的请求参数或上下文动态生成响应。</li>
<li><strong>轻松扩展</strong>:OpenResty 提供了强大的扩展能力,可以根据业务需求开发自定义模块或功能,同时也可以轻松与已有的 NGINX 模块结合使用。</li>
</ol>
<p>典型应用场景:</p>
<ul>
<li><strong>动态代理</strong>:OpenResty 可以根据请求中的信息(如请求头、URL、Cookie 等)动态调整路由和代理逻辑。</li>
<li><strong>API 网关</strong>:凭借其高性能和灵活的 Lua 脚本能力,OpenResty 常被用于构建 API 网关,通过自定义脚本实现限流、鉴权、日志记录等功能。</li>
<li><strong>缓存</strong>:可以结合 Redis 等外部缓存服务,通过 Lua 脚本灵活控制缓存策略,减少后端系统的压力。</li>
<li><strong>日志处理和监控</strong>:可以通过 Lua 实现复杂的日志处理和格式化逻辑,支持将日志数据发送到外部系统进行进一步处理和分析。</li>
</ul>
<h2><a id="1__22"></a>1 安裝下載</h2>
<p>https://openresty.org/cn/download.html</p>
<h3><a id="centos_26"></a>centos</h3>
<p>安裝基礎庫: perl 5.6.1+<code>, </code>libpcre<code>, </code>libssl</p>
<pre><div class="hljs"><code class="lang-shell"><span class="hljs-meta"># </span><span class="language-bash">ubuntu</span>
apt-get install libpcre3-dev
apt-get install libssl-dev
apt-get install perl
apt-get install make
apt-get install build-essential
apt-get install curl
<span class="hljs-meta">
# </span><span class="language-bash">Fedora 和 RedHat 用户</span>
yum install -y pcre-devel
yum install -y openssl-devel
yum install -y gcc
yum install -y curl
yum install -y zlib-devel
</code></div></pre>
<p>原创:有勇气的牛排<br />
<a href="https://www.couragesteak.com/article/472" target="_blank">https://www.couragesteak.com/article/472</a></p>
<p>準備文件</p>
<pre><div class="hljs"><code class="lang-shell">cd /usr/local
mkdir openresty
tar -zxvf openresty-1.25.3.2.tar.gz
cd openresty-1.25.3.2
</code></div></pre>
<p>構建</p>
<pre><div class="hljs"><code class="lang-shell">cd /usr/local/openresty/openresty-1.25.3.2
</code></div></pre>
<pre><div class="hljs"><code class="lang-shell">./configure --prefix=/usr/local/openresty/openresty_install \
--with-luajit \
--with-http_iconv_module \
--with-stream \
--with-stream_ssl_module
<span class="hljs-meta">
# </span><span class="language-bash">--with-luajit: 启用 LuaJIT 以支持高性能 Lua 脚本执行。</span>
<span class="hljs-meta"># </span><span class="language-bash">--with-stream/--with-stream_ssl_module: 启用 Nginx 的 Stream 模块,以支持 TCP/UDP 负载均衡和处理。</span>
<span class="hljs-meta"># </span><span class="language-bash">-- with-http_iconv_module: 处理多语言网站、旧系统兼容性:UTF-8、ISO-8859-1、GBK</span>
</code></div></pre>
<p>安裝編譯</p>
<pre><div class="hljs"><code class="lang-shell">make && make install
</code></div></pre>
<pre><div class="hljs"><code class="lang-shell">cd /usr/local/openresty/openresty_install
</code></div></pre>
<h3><a id="_89"></a>启动</h3>
<p>启动 start_openresty.sh</p>
<pre><div class="hljs"><code class="lang-shell"><span class="hljs-meta">#</span><span class="language-bash">!/bin/bash</span>
<span class="hljs-meta">
# </span><span class="language-bash">OpenResty 安装路径</span>
OPENRESTY_PATH="/usr/local/openresty/openresty_install/nginx"
<span class="hljs-meta">
# </span><span class="language-bash">启动 OpenResty</span>
<span class="hljs-meta">$</span><span class="language-bash">OPENRESTY_PATH/sbin/nginx</span>
<span class="hljs-meta">
# </span><span class="language-bash">检查是否成功启动</span>
if [ $? -eq 0 ]; then
echo "OpenResty 启动成功."
else
echo "OpenResty 启动失败."
fi
</code></div></pre>
<p>关闭: stop_openresty.sh</p>
<pre><div class="hljs"><code class="lang-shell"><span class="hljs-meta">#</span><span class="language-bash">!/bin/bash</span>
<span class="hljs-meta">
# </span><span class="language-bash">OpenResty 安装路径</span>
OPENRESTY_PATH="/usr/local/openresty/openresty_install/nginx"
<span class="hljs-meta">
# </span><span class="language-bash">关闭 OpenResty</span>
<span class="hljs-meta">$</span><span class="language-bash">OPENRESTY_PATH/sbin/nginx -s stop</span>
<span class="hljs-meta">
# </span><span class="language-bash">检查是否成功关闭</span>
if [ $? -eq 0 ]; then
echo "OpenResty 关闭成功."
else
echo "OpenResty 关闭失败."
fi
</code></div></pre>
<p>重载: reload_openresty.sh</p>
<pre><div class="hljs"><code class="lang-shell"><span class="hljs-meta">#</span><span class="language-bash">!/bin/bash</span>
<span class="hljs-meta">
# </span><span class="language-bash">OpenResty 安装路径</span>
OPENRESTY_PATH="/usr/local/openresty/openresty_install/nginx"
<span class="hljs-meta">
# </span><span class="language-bash">重载 OpenResty 配置</span>
<span class="hljs-meta">$</span><span class="language-bash">OPENRESTY_PATH/sbin/nginx -s reload</span>
<span class="hljs-meta">
# </span><span class="language-bash">检查是否成功重载</span>
if [ $? -eq 0 ]; then
echo "OpenResty 配置重载成功."
else
echo "OpenResty 配置重载失败."
fi
</code></div></pre>
<pre><div class="hljs"><code class="lang-shell">chmod +x start_openresty.sh
chmod +x stop_openresty.sh
chmod +x reload_openresty.sh
</code></div></pre>
<p>访问:</p>
<p>http://192.168.56.20/</p>
<h3><a id="_160"></a>基础库安装</h3>
<pre><div class="hljs"><code class="lang-shell">luarocks install lua-resty-mysql
luarocks install lua-cjson
luarocks install lua-resty-http
</code></div></pre>
<h2><a id="2_HTTP_170"></a>2 HTTP方法常量</h2>
<pre><div class="hljs"><code class="lang-lua">ngx.HTTP_GET
ngx.HTTP_HEAD
ngx.HTTP_PUT
ngx.HTTP_POST
ngx.HTTP_DELETE
ngx.HTTP_OPTIONS (v0<span class="hljs-number">.5</span><span class="hljs-number">.0</span>rc24 版本加入)
ngx.HTTP_MKCOL (v0<span class="hljs-number">.8</span><span class="hljs-number">.2</span> 版本加入)
ngx.HTTP_COPY (v0<span class="hljs-number">.8</span><span class="hljs-number">.2</span> 版本加入)
ngx.HTTP_MOVE (v0<span class="hljs-number">.8</span><span class="hljs-number">.2</span> 版本加入)
ngx.HTTP_PROPFIND (v0<span class="hljs-number">.8</span><span class="hljs-number">.2</span> 版本加入)
ngx.HTTP_PROPPATCH (v0<span class="hljs-number">.8</span><span class="hljs-number">.2</span> 版本加入)
ngx.HTTP_LOCK (v0<span class="hljs-number">.8</span><span class="hljs-number">.2</span> 版本加入)
ngx.HTTP_UNLOCK (v0<span class="hljs-number">.8</span><span class="hljs-number">.2</span> 版本加入)
ngx.HTTP_PATCH (v0<span class="hljs-number">.8</span><span class="hljs-number">.2</span> 版本加入)
ngx.HTTP_TRACE (v0<span class="hljs-number">.8</span><span class="hljs-number">.2</span> 版本加入)
</code></div></pre>
<h2><a id="3_HTTP_190"></a>3 HTTP状态常量</h2>
<pre><div class="hljs"><code class="lang-lua">value = ngx.HTTP_OK (等于 <span class="hljs-number">200</span>)
value = ngx.HTTP_CREATED (等于 <span class="hljs-number">201</span>)
value = ngx.HTTP_SPECIAL_RESPONSE (等于 <span class="hljs-number">300</span>)
value = ngx.HTTP_MOVED_PERMANENTLY (等于 <span class="hljs-number">301</span>)
value = ngx.HTTP_MOVED_TEMPORARILY (等于 <span class="hljs-number">302</span>)
value = ngx.HTTP_SEE_OTHER (等于 <span class="hljs-number">303</span>)
value = ngx.HTTP_NOT_MODIFIED (等于 <span class="hljs-number">304</span>)
value = ngx.HTTP_BAD_REQUEST (等于 <span class="hljs-number">400</span>)
value = ngx.HTTP_UNAUTHORIZED (等于 <span class="hljs-number">401</span>)
value = ngx.HTTP_FORBIDDEN (等于 <span class="hljs-number">403</span>)
value = ngx.HTTP_NOT_FOUND (等于 <span class="hljs-number">404</span>)
value = ngx.HTTP_NOT_ALLOWED (等于 <span class="hljs-number">405</span>)
value = ngx.HTTP_GONE (等于 <span class="hljs-number">410</span>)
value = ngx.HTTP_INTERNAL_SERVER_ERROR (等于 <span class="hljs-number">500</span>)
value = ngx.HTTP_METHOD_NOT_IMPLEMENTED (等于 <span class="hljs-number">501</span>)
value = ngx.HTTP_SERVICE_UNAVAILABLE (等于 <span class="hljs-number">503</span>)
value = ngx.HTTP_GATEWAY_TIMEOUT (等于 <span class="hljs-number">504</span>) (v0<span class="hljs-number">.3</span><span class="hljs-number">.1</span>rc38 版本加入)
</code></div></pre>
<h2><a id="4_API_216"></a>4 语法API</h2>
<h3><a id="21_ngxsay_218"></a>2.1 ngx.say</h3>
<p>返回结果给客户端</p>
<p>语法:<code>ngx.say("")</code></p>
<pre><code class="lang-nginx">location / {
default_type 'text/plain';
content_by_lua_block {
ngx.say("牛逼")
}
}
</code></pre>
<p><img src="https://static.couragesteak.com/article/ff7d7d1b048f176db766ff5b2d30db95.png" alt="image.png" /></p>
<h3><a id="22_ngxprint_237"></a>2.2 ngx.print</h3>
<pre><div class="hljs"><code class="lang-lua">location / {
default_type <span class="hljs-string">'text/plain'</span>;
content_by_lua_block {
# 作为响应体返回
<span class="hljs-keyword">local</span> table_data = {
<span class="hljs-string">'id'</span>
}
ok, err = ngx.<span class="hljs-built_in">print</span>(table_data)
ngx.say(<span class="hljs-string">"有勇氣的牛排"</span>)
}
}
</code></div></pre>
<p><img src="E:%5Cblog_article%5CLua%5C5d8ecc6d17a76a940dbe4dae6a331468.png" alt="image.png" /></p>
<h3><a id="23_ngxflush_258"></a>2.3 ngx.flush</h3>
<p>定义:用户强制将nginx的输出缓冲区的内容,立即发送给客户端。</p>
<p>通常在调用 <code>ngx.print</code> 后使用,确保数据及时传递到客户端。</p>
<p>场景:</p>
<ul>
<li>实时发送数据流</li>
<li>长轮训</li>
<li>分块传输编码(chunked transfer encoding)</li>
</ul>
<pre><div class="hljs"><code class="lang-lua">ngx.<span class="hljs-built_in">print</span>(<span class="hljs-string">'...'</span>)
ngx.<span class="hljs-built_in">flush</span>(<span class="hljs-literal">true</span>)
</code></div></pre>
<p>参数:</p>
<ul>
<li>wait:可选</li>
<li>true:表示将等待数据发送完成后再继续处理</li>
</ul>
<p>注意:</p>
<ul>
<li>
<p>这会增加网络开销,因为它会打破数据包的聚合,从而导致更多的TCP包发送。</p>
</li>
<li>
<p>会影响性能。</p>
</li>
</ul>
<h3><a id="24_ngxarg_286"></a>2.4 ngx.arg</h3>
<h3><a id="25_ngxvar_nginx_290"></a>2.5 ngx.var 获取nginx变量</h3>
<p>获取值</p>
<pre><div class="hljs"><code class="lang-lua"><span class="hljs-keyword">local</span> uri = ngx.var.uri <span class="hljs-comment">-- 获取当前请求的 URI</span>
<span class="hljs-keyword">local</span> uri = ngx.var.request_method <span class="hljs-comment">-- 当前请求的方法GET、POST等</span>
<span class="hljs-keyword">local</span> uri = ngx.var.args <span class="hljs-comment">-- 当前请求的查询参数</span>
<span class="hljs-keyword">local</span> uri = ngx.var.remote_addr <span class="hljs-comment">-- 客户端的 IP 地址</span>
</code></div></pre>
<p>设置自定义变量值(如果nx)</p>
<pre><div class="hljs"><code class="lang-lua">ngx.var.some_variable = <span class="hljs-string">"new_value"</span>
</code></div></pre>
<p>注意:</p>
<ul>
<li>
<p>ngx中部分变量为只读</p>
</li>
<li>
<p>在设置变量时,如果ngx没有定义,则可能报错</p>
</li>
</ul>
<h3><a id="26_ngxlog__313"></a>2.6 ngx.log 输出日志</h3>
<pre><div class="hljs"><code class="lang-lua">ngx.STDERR <span class="hljs-comment">-- 标准错误输出,用于记录严重错误</span>
ngx.EMERG <span class="hljs-comment">-- 紧急情况,表示系统不可用</span>
ngx.ALERT <span class="hljs-comment">-- 需要立即采取行动的错误</span>
ngx.CRIT <span class="hljs-comment">-- 严重的错误</span>
ngx.ERR <span class="hljs-comment">-- 一般错误</span>
ngx.WARN <span class="hljs-comment">-- 警告信息,可能存在问题</span>
ngx.NOTICE <span class="hljs-comment">-- 普通通知信息,表示状态变化</span>
ngx.INFO <span class="hljs-comment">-- 一般信息,记录应用程序的正常操作</span>
ngx.DEBUG <span class="hljs-comment">-- 调试信息,记录程序细节</span>
</code></div></pre>
<p>使用</p>
<pre><div class="hljs"><code class="lang-lua">ngx.<span class="hljs-built_in">log</span>(ngx.ERR, <span class="hljs-string">'异常: '</span>, <span class="hljs-string">'错误信息ERR'</span>)
ngx.<span class="hljs-built_in">log</span>(ngx.INFO, <span class="hljs-string">'IP地址: '</span>, ngx.var.remote_addr)
ngx.<span class="hljs-built_in">log</span>(ngx.DEBUG, <span class="hljs-string">'URI地址为: '</span>, ngx.var.uri)
</code></div></pre>
<p>输出结果在:error.log文件中</p>
<p><img src="https://static.couragesteak.com/article/949b10e8f7baedb02e95a517fa6577b6.png" alt="image.png" /></p>
<p>如果看不到结果,请配置</p>
<pre><code class="lang-nginx"># nginx.conf 第7行左右
error_log logs/error.log debug;
</code></pre>
<h3><a id="27_ngxctx_346"></a>2.7 ngx.ctx</h3>
<p>location里面的全局变量/上下文变量</p>
<h3><a id="ngxexit_352"></a>ngx.exit</h3>
<h3><a id="ngxsleep_356"></a>ngx.sleep</h3>
<pre><div class="hljs"><code class="lang-lua">ngx.sleep(<span class="hljs-number">1000</span>)
</code></div></pre>
<h2><a id="5_API_362"></a>5 请求API</h2>
<h3><a id="arg__364"></a>arg 参数</h3>
<h4><a id="GET__366"></a>GET 参数</h4>
<pre><div class="hljs"><code class="lang-shell">http://127.0.0.1/?id=1&name=有勇气的牛排
</code></div></pre>
<p><strong>ngx.req.get_post_args: V1.25.3.2版本已经无法使用</strong></p>
<p><strong>老方法(不知道哪个版本在用)</strong></p>
<pre><div class="hljs"><code class="lang-lua"><span class="hljs-comment">-- 获取 URL 参数</span>
<span class="hljs-keyword">local</span> args = ngx.req.get_url_args()
<span class="hljs-comment">-- 获取具体的参数</span>
<span class="hljs-keyword">local</span> id = args[<span class="hljs-string">"id"</span>]
lcoal age = args[<span class="hljs-string">"name"</span>]
<span class="hljs-comment">-- 输出参数</span>
ngx.say(<span class="hljs-string">"昵称:"</span>, name)
ngx.say(<span class="hljs-string">"ID:"</span>, id)
</code></div></pre>
<p>新语法:V1.25.3.2语法</p>
<pre><div class="hljs"><code class="lang-lua"><span class="hljs-comment">-- 获取 URL 参数</span>
<span class="hljs-keyword">local</span> id = ngx.var.arg_id
<span class="hljs-keyword">local</span> name = ngx.var.arg_name
<span class="hljs-comment">-- 输出参数</span>
ngx.say(<span class="hljs-string">"昵称:"</span>, name)
ngx.say(<span class="hljs-string">"ID:"</span>, id)
</code></div></pre>
<h4><a id="POST_401"></a>POST参数</h4>
<p><strong>ngx.req.get_post_args: V1.25.3.2版本已经无法使用</strong></p>
<pre><div class="hljs"><code class="lang-lua"><span class="hljs-comment">-- 获取 URL 参数(GET/POST)</span>
<span class="hljs-keyword">local</span> id = ngx.var.arg_id
<span class="hljs-keyword">local</span> name = ngx.var.arg_name
<span class="hljs-comment">-- 输出参数</span>
ngx.say(<span class="hljs-string">"昵称:"</span>, name)
ngx.say(<span class="hljs-string">"ID:"</span>, id)
</code></div></pre>
<h3><a id="method__417"></a>method 方法</h3>
<h4><a id="ngxreqget_method_419"></a>ngx.req.get_method()</h4>
<pre><div class="hljs"><code class="lang-lua"><span class="hljs-keyword">local</span> http_method = ngx.req.get_method()
ngx.say(<span class="hljs-string">"方法:"</span>, http_method)
</code></div></pre>
<p><img src="https://static.couragesteak.com/article/c621b715c4eb400a548382e147c571a1.png" alt="image.png" /></p>
<h4><a id="ngxreqset_method_428"></a>ngx.req.set_method</h4>
<pre><div class="hljs"><code class="lang-lua">ngx.req.set_method(ngx.HTTP_GET)
</code></div></pre>
<h3><a id="header_434"></a>header操作</h3>
<p>添加、修改、清除请求头</p>
<pre><div class="hljs"><code class="lang-lua"><span class="hljs-comment">-- 2种語法</span>
ngx.header.content_type = <span class="hljs-string">'text/plain'</span>;
ngx.header[<span class="hljs-string">"My-Header"</span>] = <span class="hljs-string">'有勇气的牛排'</span>
</code></div></pre>
<p><img src="https://static.couragesteak.com/article/27ea725e915a906ea7bacade70caaa48.png" alt="image.png" /></p>
<h3><a id="__448"></a>重定向 跳转</h3>
<h4><a id="ngxredirect_450"></a>ngx.redirect</h4>
<p>注意:跳转第三方网站添加 https</p>
<pre><div class="hljs"><code class="lang-shell">http://127.0.0.1/
</code></div></pre>
<pre><div class="hljs"><code class="lang-lua"><span class="hljs-comment">-- 3种语法</span>
<span class="hljs-keyword">return</span> ngx.redirect(<span class="hljs-string">"/test"</span>)
<span class="hljs-keyword">return</span> ngx.redirect(<span class="hljs-string">"/test"</span>, <span class="hljs-number">301</span>)
<span class="hljs-keyword">return</span> ngx.redirect(<span class="hljs-string">"https://www.couragesteak.com/"</span>, ngx.HTTP_MOVED_TEMPORARILY)
</code></div></pre>
<h4><a id="ngxexec_467"></a>ngx.exec</h4>
<p>内部跳转</p>
<h2><a id="_API_473"></a>指令 API</h2>
<h3><a id="init_by_lua_475"></a>init_by_lua</h3>
<p>Master 进程被创建时执行</p>
<p>该指令在 nginx 重新加载配置时执行,可以将耗时的模块提前加载,或者初始化全局变量。</p>
<p>即:公共模块</p>
<pre><div class="hljs"><code class="lang-lua">lua_by_lua_block {
<span class="hljs-comment">-- 全局导入 MySQL 和 Redis</span>
mysql = <span class="hljs-built_in">require</span> <span class="hljs-string">"resty.mysql"</span>
redis = <span class="hljs-built_in">require</span> <span class="hljs-string">"resty.redis"</span>
my_global_var = <span class="hljs-string">"这是一个全局变量"</span>
}
</code></div></pre>
<p><img src="https://static.couragesteak.com/article/363bb89e7136f408ebde8657bf0d3cbb.png" alt="image.png" /></p>
<p>可以导入,也可以直接写</p>
<h3><a id="init_worker_by_lua_497"></a>init_worker_by_lua</h3>
<p>每个 Worker 进程(工作进程)被创建时执行</p>
<h3><a id="content_by_lua_503"></a>content_by_lua</h3>
<h2><a id="_507"></a>注</h2>
<h3><a id="_509"></a>编译配置</h3>
<pre><div class="hljs"><code class="lang-shell">[root@master openresty-1.25.3.2]# ./configure --help
--help 显示此帮助信息
--prefix=PATH 设置安装前缀目录(默认路径为 /usr/local/openresty)
--with-debug 启用调试日志记录
--with-no-pool-patch 启用 no-pool 补丁以调试内存问题
-jN 在构建 LuaJIT 2.1 时传递 -jN 选项
--without-http_echo_module 禁用 ngx_http_echo_module
--without-http_xss_module 禁用 ngx_http_xss_module
--without-http_coolkit_module 禁用 ngx_http_coolkit_module
--without-http_set_misc_module 禁用 ngx_http_set_misc_module
--without-http_form_input_module 禁用 ngx_http_form_input_module
--without-http_encrypted_session_module
禁用 ngx_http_encrypted_session_module
--without-http_srcache_module 禁用 ngx_http_srcache_module
--without-http_lua_module 禁用 ngx_http_lua_module
--without-http_lua_upstream_module 禁用 ngx_http_lua_upstream_module
--without-http_headers_more_module 禁用 ngx_http_headers_more_module
--without-http_array_var_module 禁用 ngx_http_array_var_module
--without-http_memc_module 禁用 ngx_http_memc_module
--without-http_redis2_module 禁用 ngx_http_redis2_module
--without-http_redis_module 禁用 ngx_http_redis_module
--without-http_rds_json_module 禁用 ngx_http_rds_json_module
--without-http_rds_csv_module 禁用 ngx_http_rds_csv_module
--without-stream_lua_module 禁用 ngx_stream_lua_module
--without-ngx_devel_kit_module 禁用 ngx_devel_kit_module
--without-stream 禁用 TCP/UDP 代理模块
--without-http_ssl_module 禁用 ngx_http_ssl_module
--without-stream_ssl_module 禁用 ngx_stream_ssl_module
--with-http_iconv_module 启用 ngx_http_iconv_module
--with-http_drizzle_module 启用 ngx_http_drizzle_module
--with-http_postgres_module 启用 ngx_http_postgres_module
--without-lua_cjson 禁用 lua-cjson 库
--without-lua_tablepool 禁用 lua-tablepool 库(因此也禁用 lua-resty-shell 库)
--without-lua_redis_parser 禁用 lua-redis-parser 库
--without-lua_rds_parser 禁用 lua-rds-parser 库
--without-lua_resty_dns 禁用 lua-resty-dns 库
--without-lua_resty_memcached 禁用 lua-resty-memcached 库
--without-lua_resty_redis 禁用 lua-resty-redis 库
--without-lua_resty_mysql 禁用 lua-resty-mysql 库
--without-lua_resty_upload 禁用 lua-resty-upload 库
--without-lua_resty_upstream_healthcheck
禁用 lua-resty-upstream-healthcheck 库
--without-lua_resty_string 禁用 lua-resty-string 库
--without-lua_resty_websocket 禁用 lua-resty-websocket 库
--without-lua_resty_limit_traffic 禁用 lua-resty-limit-traffic 库
--without-lua_resty_lock 禁用 lua-resty-lock 库
--without-lua_resty_lrucache 禁用 lua-resty-lrucache 库
--without-lua_resty_signal 禁用 lua-resty-signal 库(因此也禁用 lua-resty-shell 库)
--without-lua_resty_shell 禁用 lua-resty-shell 库
--without-lua_resty_core 禁用 lua-resty-core 库
--with-luajit=DIR 使用由 DIR 指定的外部 LuaJIT 2.1 安装
--with-luajit-xcflags=FLAGS 为 LuaJIT 2.1 指定额外的 C 编译器标志
--with-luajit-ldflags=FLAGS 为 LuaJIT 2.1 指定额外的 C 链接器标志
--without-luajit-lua52 禁用 LuaJIT 5.2 的扩展,以防止破坏向后兼容性
--without-luajit-gc64 禁用 LuaJIT 的 GC64 模式(在 x86_64 上默认启用)
--with-libdrizzle=DIR 指定 libdrizzle 1.0(或 drizzle)安装前缀
--with-libpq=DIR 指定 libpq(或 postgresql)安装前缀
--with-pg_config=PATH 指定 pg_config 工具的路径
Nginx 的选项继承:
--sbin-path=PATH 设置 nginx 二进制文件的路径
--modules-path=PATH 设置模块路径
--conf-path=PATH 设置 nginx.conf 文件路径
--error-log-path=PATH 设置错误日志文件路径
--pid-path=PATH 设置 nginx.pid 文件路径
--lock-path=PATH 设置 nginx.lock 文件路径
--user=USER 设置 worker 进程的非特权用户
--group=GROUP 设置 worker 进程的非特权用户组
--build=NAME 设置构建名称
--builddir=DIR 设置构建目录
--with-select_module 启用 select 模块
--without-select_module 禁用 select 模块
--with-poll_module 启用 poll 模块
--without-poll_module 禁用 poll 模块
--with-threads 启用线程池支持
--with-file-aio 启用文件 AIO 支持
--with-http_ssl_module 启用 ngx_http_ssl_module(默认启用)
--with-http_v2_module 启用 ngx_http_v2_module
--with-http_v3_module 启用 ngx_http_v3_module
--with-http_realip_module 启用 ngx_http_realip_module
--with-http_addition_module 启用 ngx_http_addition_module
--with-http_xslt_module 启用 ngx_http_xslt_module
--with-http_xslt_module=dynamic 启用动态 ngx_http_xslt_module
--with-http_image_filter_module 启用 ngx_http_image_filter_module
--with-http_image_filter_module=dynamic
启用动态 ngx_http_image_filter_module
--with-http_geoip_module 启用 ngx_http_geoip_module
--with-http_geoip_module=dynamic 启用动态 ngx_http_geoip_module
--with-http_sub_module 启用 ngx_http_sub_module
--with-http_dav_module 启用 ngx_http_dav_module
--with-http_flv_module 启用 ngx_http_flv_module
--with-http_mp4_module 启用 ngx_http_mp4_module
--with-http_gunzip_module 启用 ngx_http_gunzip_module
--with-http_gzip_static_module 启用 ngx_http_gzip_static_module
--with-http_auth_request_module 启用 ngx_http_auth_request_module
--with-http_random_index_module 启用 ngx_http_random_index_module
--with-http_secure_link_module 启用 ngx_http_secure_link_module
--with-http_degradation_module 启用 ngx_http_degradation_module
--with-http_slice_module 启用 ngx_http_slice_module
--with-http_stub_status_module 启用 ngx_http_stub_status_module
--without-http_charset_module 禁用 ngx_http_charset_module
--without-http_gzip_module 禁用 ngx_http_gzip_module
--without-http_ssi_module 禁用 ngx_http_ssi_module
--without-http_userid_module 禁用 ngx_http_userid_module
--without-http_access_module 禁用 ngx_http_access_module
--without-http_auth_basic_module 禁用 ngx_http_auth_basic_module
--without-http_mirror_module 禁用 ngx_http_mirror_module
--without-http_autoindex_module 禁用 ngx_http_autoindex_module
--without-http_geo_module 禁用 ngx_http_geo_module
--without-http_map_module 禁用 ngx_http_map_module
--without-http_split_clients_module 禁用 ngx_http_split_clients_module
--without-http_referer_module 禁用 ngx_http_referer_module
--without-http_rewrite_module 禁用 ngx_http_rewrite_module
--without-http_proxy_module 禁用 ngx_http_proxy_module
--without-http_fastcgi_module 禁用 ngx_http_fastcgi_module
--without-http_uwsgi_module 禁用 ngx_http_uwsgi_module
--without-http_scgi_module 禁用 ngx_http_scgi_module
--without-http_grpc_module 禁用 ngx_http_grpc_module
--without-http_memcached_module 禁用 ngx_http
</code></div></pre>
留言