openresty 跑定时任务配置、ngx.timer.every接口使用

April 19, 2021

这篇文章主要介绍了如何在OpenResty中配置和使用定时任务。首先,文章解释了定时任务需要与worker绑定,通常默认绑定到worker_id=0,这样在Nginx进程中只执行一个timer。然后,文章提供了在nginx.conf中配置定时任务的具体方法。接着,文章介绍了如何使用ngx.timer.every接口,这是ngx提供的最新接口。最后,文章提供了一些相关的日志输出和错误处理方法。

openresty的定时任务是要跟worker绑定的。如果不绑定特定的worker,那么所有启动的woker都会去执行定时任务。

一般情况下默认绑定worker_id=0的,这样在nginx整个进程里面,就只执行一个timer。

在conf中具体的位置可以写自己的任务逻辑。

具体的nginx.conf配置如下:

worker_processes  1;
error_log logs/error.log;
events {
    worker_connections 1024;
}


http {
    init_worker_by_lua_block {
         local delay = 2  -- in seconds
         local new_timer = ngx.timer.at
         local log = ngx.log
         local ERR = ngx.ERR
         local check

         check = function(premature)
             if not premature then
                 -- do the health check or other routine work
                 log(ERR, "mm test mm test")
                 local ok, err = new_timer(delay, check)
                 if not ok then
                     log(ERR, "failed to create timer: ", err)
                     return
                 end
             end
         end

         if 0 == ngx.worker.id() then
             local ok, err = new_timer(delay, check)
             if not ok then
                 log(ERR, "failed to create timer: ", err)
                 return
             end
         end
    }

    server {
        listen 8081;
        location / {
            default_type text/html;
            content_by_lua '
                ngx.say("<p>hello, world</p>")
            ';
        }

        location = /app/test {
            content_by_lua_block {
                local res = ngx.location.capture(
                                "/sum", {args={a=3, b=8}}
                                )
                ngx.say("status:", res.status, " response:", res.body)
            }
        }
        location = /sum {
            internal;
            content_by_lua_block {
                ngx.sleep(0.1)
                local args = ngx.req.get_uri_args()
                ngx.print(tonumber(args.a) + tonumber(args.b))
            }
        }

        location = /subduction {
            internal;
            content_by_lua_block {
                ngx.sleep(0.1)
                local args = ngx.req.get_uri_args()
                ngx.print(tonumber(args.a) - tonumber(args.b))
            }
        }

        location = /app/test_parallels {
            content_by_lua_block {
                local start_time = ngx.now()
                local res1, res2 = ngx.location.capture_multi( {
                                {"/sum", {args={a=3, b=8}}},
                                {"/subduction", {args={a=3, b=8}}}
                            })
                ngx.say("status:", res1.status, " response:", res1.body)
                ngx.say("status:", res2.status, " response:", res2.body)
                ngx.say("time used:", ngx.now() - start_time)
            }
        }

        location = /app/test_queue {
            content_by_lua_block {
                local start_time = ngx.now()
                local res1 = ngx.location.capture_multi( {
                                {"/sum", {args={a=3, b=8}}}
                            })
                local res2 = ngx.location.capture_multi( {
                                {"/subduction", {args={a=3, b=8}}}
                            })
                ngx.say("status:", res1.status, " response:", res1.body)
                ngx.say("status:", res2.status, " response:", res2.body)
                ngx.say("time used:", ngx.now() - start_time)
            }
        }
}
}

注意init_worker_by_lua_block是放在http里面的。因为此处只配置了error.log,因此是打印的err级别的日志,方便观察。

接下来启动ngin:sudo nginx -p pwd/ -c conf/nginx.conf

然后tailf logs/error.log:

img

追日志会发现,每隔2s就会打印一条日志。

二、使用ngx.timer.every接口

ngx提供了最新的ngx.timer.every接口,再来试一下:

    init_worker_by_lua_block {
         local delay = 2  -- in seconds
         -- local new_timer = ngx.timer.at
         local log = ngx.log
         local ERR = ngx.ERR
         local check

         check = function(premature)
             if not premature then
                 -- do the health check or other routine work
                 log(ERR, "mm test mm test")
                 -- local ok, err = new_timer(delay, check)
                 -- if not ok then
                 --     log(ERR, "failed to create timer: ", err)
                 --     return
                 --  end
             end
         end

         if 0 == ngx.worker.id() then
             local ok, err = ngx.timer.every(delay, check)
             if not ok then
                 log(ERR, "failed to create timer: ", err)
                 return
             end
         end
    }

转自

https://www.cnblogs.com/sonofelice/p/8259712.html

Luatimer

IARNO

服务端开发

ngx_lua模块中使用lua_shared_dict共享内存变量

too many open files 问题定位