OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。
OpenResty® 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。
# 英文官网
http://openresty.org/
# 中文官网
https://openresty.org/cn/
## 优秀的参考文章
https://moonbingbing.gitbooks.io/openresty-best-practices
## 源码包编译安装
./configure --prefix=/usr/local/openresty/ --conf-path=/etc/nginx/nginx.conf
线上编译参数参考:
$nginx -V
nginx version: openresty/1.15.8.2
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/openresty/nginx --with-debug --with-cc-opt='-DNGX_LUA_USE_ASSERT -DNGX_LUA_ABORT_AT_PANIC -O2 -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -fPIC' --add-module=../ngx_devel_kit-0.3.1rc1 --add-module=../echo-nginx-module-0.61 --add-module=../xss-nginx-module-0.06 --add-module=../ngx_coolkit-0.2 --add-module=../set-misc-nginx-module-0.32 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.08 --add-module=../srcache-nginx-module-0.31 --add-module=../ngx_lua-0.10.15 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.33 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.19 --add-module=../redis2-nginx-module-0.15 --add-module=../redis-nginx-module-0.3.7 --add-module=../rds-json-nginx-module-0.15 --add-module=../rds-csv-nginx-module-0.09 --add-module=../ngx_stream_lua-0.0.7 --with-ld-opt='-Wl,-rpath,/usr/local/openresty/luajit/lib -Wl,-z,relro -Wl,-z,now -pie' --conf-path=/etc/nginx/nginx.conf --with-file-aio --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_ssl_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-http_stub_status_module --add-module=/home/qq/openresty-1.15.8.2/nginx-module-vts --add-module=/home/qq/openresty-1.15.8.2/nginx-http-sysguard --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module
使用systemd 托管
cd /usr/lib/systemd/system/
[Unit]
Description=The OpenResty Application Platform
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/openresty/nginx/logs/nginx.pid
ExecStartPre=/usr/local/openresty/nginx/sbin/nginx -t
ExecStart=/usr/local/openresty/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
名称 | 解释 |
ngx.arg | 指令参数,如跟在content_by_lua_file后面的参数 |
ngx.var | request变量,ngx.var.VARIABLE引用某个变量 |
ngx.ctx | 请求的lua上下文 |
ngx.header | 响应头,ngx.header.HEADER引用某个头 |
ngx.status | 响应码 |
ngx.log | 输出到error.log |
ngx.send_headers | 发送响应头 |
ngx.headers_sent | 响应头是否已发送 |
ngx.resp.get_headers | 获取响应头 |
ngx.is_subrequest | 当前请求是否是子请求 |
ngx.location.capture | 发布一个子请求 |
ngx.location.capture_multi | 发布多个子请求 |
ngx.print | 输出响应 |
ngx.say | 输出响应,自动添加‘\n‘ |
ngx.flush | 刷新响应 |
ngx.exit | 结束请求 |
Nginx执行lua脚本片断时,需要明确指明执行的nginx阶段时机。主要有以下几种时机:
##
server {
listen 80;
server_name xx.cn;
charset utf-8;
# 默认读取 body
lua_need_request_body on;
location / {
default_type text/html;
content_by_lua_block {
local res = " local var"
-- ngx.sleep(3)
ngx.say("{\"name\":\"tom\"}",res)
}
}
# 获取请求body
location /test{
content_by_lua_block {
local data = ngx.req.get_body_data()
ngx.say("hello ", data)
ngx.print("------")
local str="aaaa"
ngx.log(ngx.INFO,"string",str)
}
}
# 测试: curl 'http://xx.cn/sum?a=11&b=12'
location /sum {
content_by_lua_block {
local a = tonumber(ngx.var.arg_a) or 0
local b = tonumber(ngx.var.arg_b) or 0
ngx.say("sum: ", a + b )
}
}
# 黑白名单限制
location /black {
access_by_lua_block {
local black_ips = {["192.168.106.161"]=true,["192.168.106.162"]=true}
local ip = ngx.var.remote_addr
if true == black_ips[ip] then
ngx.exit(ngx.HTTP_FORBIDDEN)
end
}
# 处理业务
content_by_lua_block {
ngx.say("test black white ip list")
}
}
# 获取get参数,ngx.var--取请求参数,arg_a指参数a
# curl xx.cn/args?a=xx&b=yy
location /args {
content_by_lua_block{
ngx.say(ngx.var.arg_a)
ngx.say(ngx.var.arg_b)
}
}
# lua取request中header信息
location /head {
access_by_lua_file "/etc/nginx/conf/lua/lua_req.lua";
echo "hello---";
}
access_log /home/data/logs/xx.cn/xx.cn.access.logstash_json logstash_json;
}
lua脚本如下:
$ cat lua_req.lua
-- 读请求头信息
local headers = ngx.req.get_headers()
ngx.say("Host : ", headers.Host)
ngx.say("Host : ", headers["Host"])
$ cat set.lua
local a=tonumber(ngx.arg[1])
local b=tonumber(ngx.arg[2])
return a + b
# 发送get请求
$ curl "http://xx.cn/setfile?a=100&b=200"
300
nginx配置如下:
# 给lua脚本传参
location /setfile {
set_by_lua_file $val "/etc/nginx/conf/lua/set.lua" $arg_a $arg_b;
echo $val;
}
一般校验动作,指定在access阶段执行脚本。
$ cat access.lua
if ngx.var.arg_passwd == "123456"
then
return
else
ngx.exit(ngx.HTTP_FORBIDDEN)
end
nginx的配置如下:
# 权限校验
location /access {
access_by_lua_file "/etc/nginx/conf/lua/access.lua";
echo "xxx";
}
Nginx有时候,需要对下游服务生成的内容进行处理过滤,如下:
[www@me01 lua]$ cat filter.lua
local chunk = ngx.arg[1
if string.match(chunk, "hello") then
ngx.arg[2] = true
return
end
ngx.arg[1] = nil
Nginx配置如下:
# 内容过滤
location /filter {
echo "111";
echo "222";
body_filter_by_lua_file "/etc/nginx/conf/lua/filter.lua";
}
OpenResty提供了非常多的第三方插件,支持操作redis/mysql等服务,lua使用它们的模式一般按以下流程。
插件地址:
##
https://github.com/openresty/lua-resty-redis
Ng配置如下:
# 连接redis
location /redis {
access_by_lua_file "/etc/nginx/conf/lua/access_by_redis.lua";
}