本篇是从https://legacy.gitbook.com/book/moonbingbing/openresty-best-practices 学习记录的,目的是为了查询方便。
使用docker运行镜像
docker run --name openresty -d -p 80:80 -v /Users/zhangyong/Documents/docker/openresty/openresty/conf:/usr/local/openresty/nginx/conf openresty/openresty:focal-nosse42
测试一个lua写法,包括了并发请求。
server {
listen 80;
location / {
default_type text/html;
content_by_lua_block {
ngx.say("HelloWorld")
local res_add = ngx.location.capture(
"/add",{args={a=2, b=7}}
)
ngx.say(res_add.body)
local res1,res2 = ngx.location.capture_multi({
{"/add",{args={a=3, b=7}}},
{"/del",{args={a=3, b=7}}}
})
ngx.say(res1.body,"---",res2.body)
}
}
location /add {
internal; #内部调用的路由
content_by_lua_block{
local args = ngx.req.get_uri_args()
ngx.say(tonumber(args.a) + tonumber(args.b))
}
}
location /del {
internal; #内部调用的路由
content_by_lua_block{
local args = ngx.req.get_uri_args()
ngx.say(tonumber(args.a) - tonumber(args.b))
}
}
}
location = / {
rewrite_by_lua_block {
return ngx.redirect('/add'); # 重定向
}
}
ngx.req.get_uri_args、ngx.req.get_post_args
前者来自 uri 请求参数,而后者来自 post 请求内容。由于 Nginx 是为了解决负载均衡场景诞生的,所以它默认是不读取 body 的行为,post参数需要加 ngx.req.read_body()
或者在外层指定lua_need_request_body on;
如下发送post到location的请求。ngx.location.capture是异步的、res = ngx.location.capture(
'/foo/bar',
{ method = ngx.HTTP_POST, body = 'hello, world' }
)
得到响应返回一个包含四个元素的 Lua 表 (res.status, res.header, res.body, 和 res.truncated)。res.truncated是截断,布尔值标记来判断 res.body 是否包含截断的数据。这种数据截断的原因只可能是因为子请求发生了不可恢复的错误,例如远端在发送响应体时过早中断了连接,或子请求在接收远端响应体时超时。
while true do
data = file:read(1024)
if nil == data then
break
end
ngx.print(data)
ngx.flush(true)
end
error_log logs/error.log info;
指定info为error/其他日志级别ngx.log(ngx.ERR, "this is error log")
access_by_lua_file
做参数校验。location ~ ^/api/([-_a-zA-Z0-9/]+) {
access_by_lua_file lua/access_check.lua;
content_by_lua_file lua/$1.lua;
}
location /download {
access_by_lua_block {
ngx.var.limit_rate = 1000
}
content_by_lua_block{
ngx.say(1111)
}
}
通过wget '127.0.0.1/download/1.cab'
访问可以将返回结果保存到 1.cab里面。
local http = require "resty.http"
local httpc = http.new()
local data = {}
local res, err = httpc:request_uri(
"http://127.0.0.1:81/hello",
{
method = "POST",
body = data,
}
)
local ok, t = pcall(test_method, str)
if not ok then
return nil
end
return t
set_by_lua*: 流程分支处理判断变量初始化
rewrite_by_lua*: 转发、重定向、缓存等功能(例如特定请求代理到外网)
access_by_lua*: IP 准入、接口权限等情况集中处理(例如配合 iptable 完成简单防火墙)
content_by_lua*: 内容生成
header_filter_by_lua*: 响应头部过滤处理(例如添加头部信息)
body_filter_by_lua*: 响应体过滤处理(例如完成应答内容统一成大写)
log_by_lua*: 会话完成后本地异步完成日志记录(日志可以记录在本地,还可以同步到其他机器)
lua_code_cache off
改完lua 不用重启lua_shared_dict my_cache 128m;
这个 cache 是 Nginx 所有 worker 之间共享的location / {
default_type text/html;
content_by_lua_block {
local cache_ngx = ngx.shared.my_cache
cache_ngx:set('key', 111, 1000)
local value = cache_ngx:get('key')
ngx.say(value)
}
}
ngx.timer.at(delay,function)
init_by_lua* 和 init_worker_by_lua*
阶段才能定义真正的全局变量。