openresty ngx_lua定时任务


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

          

                

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用OpenResty来实现Nginx Lua定时任务OpenResty是一个基于Nginx的Web应用服务器,它可以通过Lua脚本扩展Nginx的功能。 要实现定时任务,您可以使用Lua的定时器功能。下面是一个示例代码: ```lua local delay = 5 -- 任务延迟时间(秒) local interval = 60 -- 任务执行间隔(秒) local function my_task() -- 在这里编写您的任务逻辑 -- 调用某个接口或执行其他操作 ngx.log(ngx.ERR, "定时任务执行") end -- 定时执行任务的函数 local function run_task() my_task() local ok, err = ngx.timer.at(interval, run_task) if not ok then ngx.log(ngx.ERR, "定时任务创建失败: ", err) return end end -- 延迟执行任务 local ok, err = ngx.timer.at(delay, run_task) if not ok then ngx.log(ngx.ERR, "定时任务创建失败: ", err) return end ``` 在上面的示例中,`delay` 变量定义了任务的延迟时间,`interval` 变量定义了任务的执行间隔。`my_task` 函数是您自己的任务逻辑,您可以在其中调用某个接口或执行其他操作。`run_task` 函数用于定时执行任务,并在每次任务执行完成后再次调度下一次任务。 您可以将上述代码保存为一个Lua文件,然后在Nginx配置中引入该文件,以便定时任务能够生效。例如,在Nginx的 `http` 块中添加以下指令: ```nginx location /lua_task { content_by_lua_file /path/to/your/lua_script.lua; } ``` 然后,您可以通过访问 `/lua_task` 路径来触发定时任务的执行。 请注意,这只是一个简单的示例,实际使用中可能需要根据您的具体需求进行修改和调整。另外,定时任务的执行是在Nginx worker进程中进行的,因此请确保您的任务逻辑是非阻塞的,以免影响Nginx的性能和稳定性。 希望对您有帮助!如有更多疑问,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值