openresty ngx_lua定时任务
ngx_timer_every:https://github.com/openresty/lua-nginx-module#ngxtimerevery
ngx_timer_at:https://github.com/openresty/lua-nginx-module#ngxtimerat
定时任务
ngx.timer.every:周期性执行定时任务,推荐使用该接口
语法格式:res, err = ngx.timer.every(delay, callback, arg, arg2, ...)
* 每隔delay秒执行一次,delay支持设置到0.001s,不支持设置为0s
* callback为回调函数,定时任务每次执行都会调用
* arg, arg2, ... 为传递给定时任务的参数
环境:init_worker_by_lua*、log_by_lua*、ngx.timer.*、balancer_by_lua*、
set_by_lua*、rewrite_by_lua*、content_by_lua*、access_by_lua*、
header_filter_by_lua*、body_filter_by_lua*、ssl_certificated_by_lua*、
ssl_session_fetch_by_lua*、ssl_session_store_by_lua*、ssl_client_hello_by_lua*
ngx.timer.at:周期性执行定时任务
语法格式:hdl, err = ngx.timer.at(delay, callback, arg, arg2, ...)
* delay=0时,表示立即执行任务,并且只执行一次
* delay不为0时,表示每隔delay秒执行一次任务
* callback为回调函数,定时任务每次执行都会调用
* arg, arg2, ... 表示传递给回调函数的参数
环境:init_worker_by_lua*、log_by_lua*、ngx.timer.*、balancer_by_lua*、
set_by_lua*、 rewrite_by_lua*、content_by_lua*、access_by_lua*、
header_filter_by_lua*、body_filter_by_lua*、ssl_certificate_by_lua*、
ssl_session_fetch_by_lua*、ssl_session_store_by_lua*、ssl_client_hello_by_lua
callback 函数说明
location / {
...
log_by_lua_block {
-- 回调函数:第一个参数premature,后续的参数都为创建定时任务传递的参数
local function push_data(premature, uri, args, status)
-- push the data uri, args, and status to the remote
-- via ngx.socket.tcp or ngx.socket.udp
-- (one may want to buffer the data in Lua a bit to
-- save I/O operations)
end
local ok, err = ngx.timer.at(0, push_data,
ngx.var.uri, ngx.var.args, ngx.header.status)
if not ok then
ngx.log(ngx.ERR, "failed to create timer: ", err)
return
end
-- other job in log_by_lua_block
}
}
The user callback will be called automatically by the Nginx core with the
arguments premature, user_arg1, user_arg2, and etc, where the premature
argument takes a boolean value indicating whether it is a premature timer
expiration or not, and user_arg1, user_arg2, and etc, are those (extra) user
arguments specified when calling ngx.timer.at as the remaining arguments.
* 回调函数会自动调用,参数为premature, user_arg1, user_arg2等自定义参数
* premature是一个boolean值,表明定时任务是否过期
* ser_arg1, user_arg2等是用户自定义参数
Premature timer expiration happens when the Nginx worker process is trying to
shut down, as in an Nginx configuration reload triggered by the HUP signal or
in an Nginx server shutdown. When the Nginx worker is trying to shut down, one
can no longer call ngx.timer.at to create new timers with nonzero delays and in
that case ngx.timer.at will return a "conditional false" value and a string
describing the error, that is, "process exiting"
* worker关闭的时候(hup信号、shutdown),premature返回true
* premature返回true时,delay=0的定时任务也不会调用,
* 会返回字符串conditional false,err=process exiting
定时任务中禁用的api
子请求api:ngx.location.capture
输出api:ngx.say、ngx.print、ngx.flush
请求api:ngx.req.*(以ngx.req.开头的api)
优化指令
lua_max_running_timers:限制最多运行的定时任务数量
语法格式:lua_max_running_timers count
* 限制最多同时运行的定时任务的数量
环境:http
When exceeding this limit, Nginx will stop running the callbacks of
newly expired timers and log an error message "N lua_max_running_timers
are not enough" where "N" is the current value of this directive
* 超过最大限制时,nginx会停止新的定时任务运行,
* 日志打印信息:N lua_max_running_timers are not enough
* N为设置的count值
lua_max_pending_timers:限制挂起的定时任务的数量
语法格式:lua_max_pending_timers count
* 限制最多挂起的定时任务的数量
环境:http
When exceeding this limit, the ngx.timer.at call will immediately
return nil and the error string "too many pending timers"
* 超过最大限制时,nginx会立刻返回nil,
* 返回错误信息:too many pending timers
使用示例
default.conf
server {
listen 80;
server_name localhost;
location /test {
content_by_lua_block {
local callback = function(premature, arg)
if not premature then
ngx.log(ngx.ERR, " ngx.worker.id ==> ", ngx.worker.id(), " info ==>", arg)
end
end
if ngx.worker.id() == 0 then
ngx.say("gtlx");
local res, err = ngx.timer.every(3, callback, "gtlx")
if not res then
ngx.log(ngx.ERR, " 定时任务执行失败 ==> ", err)
return
end
end
ngx.say("test")
}
}
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/openresty/nginx/html;
}
}
创建容器
docker run -it -d -p 2004:80 \
-v /Users/huli/lua/openresty/conf8/default.conf:/etc/nginx/conf.d/default.conf \
--name open8 lihu12344/openresty
使用测试
huli@hudeMacBook-Pro conf8 % curl localhost:2004/test
gtlx
test
查看日志:每隔3秒输出一次日志
huli@hudeMacBook-Pro conf8 % docker logs -f open8
172.17.0.1 - - [10/Jul/2022:08:05:14 +0000] "GET /test HTTP/1.1" 200 25 "-" "curl/7.77.0"
2022/07/10 08:05:18 [error] 8#8: *2 [lua] content_by_lua(default.conf:24):4: ngx.worker.id ==> 0 info ==>gtlx, context: ngx.timer, client: 172.17.0.1, server: 0.0.0.0:80
huli@hudeMacBook-Pro conf8 % docker logs -f open8
172.17.0.1 - - [10/Jul/2022:08:05:14 +0000] "GET /test HTTP/1.1" 200 25 "-" "curl/7.77.0"
2022/07/10 08:05:18 [error] 8#8: *2 [lua] content_by_lua(default.conf:24):4: ngx.worker.id ==> 0 info ==>gtlx, context: ngx.timer, client: 172.17.0.1, server: 0.0.0.0:80
2022/07/10 08:05:21 [error] 8#8: *3 [lua] content_by_lua(default.conf:24):4: ngx.worker.id ==> 0 info ==>gtlx, context: ngx.timer, client: 172.17.0.1, server: 0.0.0.0:80
2022/07/10 08:05:24 [error] 8#8: *4 [lua] content_by_lua(default.conf:24):4: ngx.worker.id ==> 0 info ==>gtlx, context: ngx.timer, client: 172.17.0.1, server: 0.0.0.0:80
2022/07/10 08:05:27 [error] 8#8: *5 [lua] content_by_lua(default.conf:24):4: ngx.worker.id ==> 0 info ==>gtlx, context: ngx.timer, client: 172.17.0.1, server: 0.0.0.0:80
2022/07/10 08:05:30 [error] 8#8: *6 [lua] content_by_lua(default.conf:24):4: ngx.worker.id ==> 0 info ==>gtlx, context: ngx.timer, client: 172.17.0.1, server: 0.0.0.0:80
2022/07/10 08:05:33 [error] 8#8: *7 [lua] content_by_lua(default.conf:24):4: ngx.worker.id ==> 0 info ==>gtlx, context: ngx.timer, client: 172.17.0.1, server: 0.0.0.0:80
2022/07/10 08:05:36 [error] 8#8: *8 [lua] content_by_lua(default.conf:24):4: ngx.worker.id ==> 0 info ==>gtlx, context: ngx.timer, client: 172.17.0.1, server: 0.0.0.0:80
2022/07/10 08:05:39 [error] 8#8: *9 [lua] content_by_lua(default.conf:24):4: ngx.worker.id ==> 0 info ==>gtlx, context: ngx.timer, client: 172.17.0.1, server: 0.0.0.0:80
2022/07/10 08:05:42 [error] 8#8: *10 [lua] content_by_lua(default.conf:24):4: ngx.worker.id ==> 0 info ==>gtlx, context: ngx.timer, client: 172.17.0.1, server: 0.0.0.0:80