自动摘要
正在生成中……
OpenResty
中文官网(起步页):https://openresty.org/cn/getting-started.html
安装方式:
http://openresty.org/cn/linux-packages.html#rhel
安装后
配置文件位于:/usr/local/openresty/nginx/conf, 配置默认当前目录为:/usr/local/openresty/nginx
nginx路径:/usr/local/openresty/nginx/sbin/nginx
==============
acme.sh为openresty安装证书
acme.sh --installcert -d hk64.my.to --key-file /usr/local/openresty/nginx/conf/ssl/hk64.my.to.key.pem --fullchain-file /usr/local/openresty/nginx/conf/ssl/hk64.my.to.cert.pem --reloadcmd "systemctl force-reload openresty"
==============
nginx 的参数-p:
nginx -p 指定安装目录,此时会寻找conf下的nginx.conf作为配置文件 , 也是实际上是 ngx.config.prefix() 输出的路径
nginx -p ~/openresty-test
目录结构:
除了conf/nginx.conf和logs,其余都是自动建立的目录
停止命令:
nginx -s stop -p /root/openresty-test
=============
ngx.location.capture_multi 并行执行
利用 ngx.location.capture_multi 函数,直接完成了两个子请求并行执行。
当两个请求没有相互依赖,这种方法可以极大提高查询效率。
https://moonbingbing.gitbooks.io/openresty-best-practices/content/openresty/work_with_location.html
=============
ngx.location.capture 这里有个小技巧,args 参数可以接受字符串或Lua 表
local res = ngx.location.capture('/print_param',
{
method = ngx.HTTP_POST,
args = {a = 1, b = '2&'}, -- 普通写法是使用函数转义 args = ngx.encode_args({a = 1, b = '2&'}) 或者手写转义,如body的写法
body = 'c=3&d=4%26'
}
)
ngx.say(res.body)
=============
获取请求 uri 参数
官方 API 文档,获取一个 uri 有两个方法:ngx.req.get_uri_args、ngx.req.get_post_args,二者主要的区别是参数来源有区别。
server {
listen 80;
server_name localhost;
location /print_param {
content_by_lua_block {
local arg = ngx.req.get_uri_args()
for k,v in pairs(arg) do
ngx.say("[GET ] key:", k, " v:", v)
end
ngx.req.read_body() -- 解析 body 参数之前一定要先读取 body
local arg = ngx.req.get_post_args()
for k,v in pairs(arg) do
ngx.say("[POST] key:", k, " v:", v)
end
}
}
}
=============
nginx默认不读取请求体body
需要打开 lua_need_request_body ;
..
# 默认读取 body
lua_need_request_body on;
location /test {
content_by_lua_block {
local data = ngx.req.get_body_data()
ngx.say("hello ", data)
}
}
...
或者如果只需要在特定接口读取时,需要显式调用 ngx.req.read_body() 接口:
location /test {
content_by_lua_block {
ngx.req.read_body()
local data = ngx.req.get_body_data()
ngx.say("hello ", data)
}
}
==============
body 偶尔读取不到的解决方法
ngx.req.get_body_data() 读请求体,会偶尔出现读取不到直接返回 nil 的情况。
如果请求体尚未被读取,请先调用 ngx.req.read_body (或打开 lua_need_request_body 选项强制本模块读取请求体,此方法不推荐)。
如果请求体已经被存入临时文件,请使用 ngx.req.get_body_file 函数代替。
如需要强制在内存中保存请求体,请设置 client_body_buffer_size 和 client_max_body_size 为同样大小。
参考:https://moonbingbing.gitbooks.io/openresty-best-practices/content/openresty/get_req_body.html
==============
流式响应大文件 (HTTP1.1的chunk特性)
location /test {
content_by_lua_block {
-- ngx.var.limit_rate = 1024*1024
local file, err = io.open(ngx.config.prefix() .. "data.db","r")
if not file then
ngx.log(ngx.ERR, "open file error:", err)
ngx.exit(ngx.HTTP_SERVICE_UNAVAILABLE)
end
local data
while true do
data = file:read(1024)
if nil == data then
break
end
ngx.print(data)
ngx.flush(true)
end
file:close()
}
}
==============
日志输出
定义日志输出的级别
error_log logs/error.log error; # 日志级别
使用ngx.log(ngx.log_level, 内容)如
```
local foo = "bar"
ngx.log(ngx.INFO, "foo var is : ",foo)
```
print 语句相当于INFO级别的日志
如:print([[I am logger]])
日志输出
2021/04/12 19:39:21 [notice] 29805#29805: *37 [lua] content_by_lua(log.conf:12):4: I am logger, client: xxxx, server: , request: "GET /log HTTP/1.1", host: ...
日志级别
ngx.STDERR -- 标准输出
ngx.EMERG -- 紧急报错
ngx.ALERT -- 报警
ngx.CRIT -- 严重,系统故障,触发运维告警系统
ngx.ERR -- 错误,业务不可恢复性错误
ngx.WARN -- 告警,业务中可忽略错误
ngx.NOTICE -- 提醒,业务比较重要信息
ngx.INFO -- 信息,业务琐碎日志信息,包含不同情况判断等
ngx.DEBUG -- 调试
网络日志库、
lua-resty-logger-socket 的目标是替代 Nginx 标准的 ngx_http_log_module 以非阻塞 IO 方式推送 access log 到远程服务器上。对远程服务器的要求是支持 syslog-ng 的日志服务。
==============