openresty 中含有posted_delayed_events补丁与信号量时, 对于定时器在reload时的处理有一个好的解决方案:
- 使用ngx.timer.at(0, handler, ...) 启动定时器
- 在定时器处理函数中, 需要连接时, 总是使用连接池, 不保持连接, set_keepalive在优雅退出时不会保持连接,
- 在完成任务时, 使用sema:wait(1), 时间可以是1s, 可以调整, 越小感知优雅退出越快
- 当sema:wait超时时, 使用 ngx.sleep(0), 切出当前epoll 循环一次(必须包含openresty posted_delayed_events补丁)
- 事件循环外, 大循环的ngx_event_no_timers_left 会感知到无多余定时器, 即会优雅退出
使用信号量可以避免频繁的定时任务创建
openresty-1.15.8.1 开始有 semaphore 信号量
openresty-1.11.2.5 :upgraded ngx_lua to 0.10.10: delayed-posted-event
feature: ngx.sleep(0) now always yield the control to the nginx event loop. this can be used to do voluntary CPU time slicing when running CPU intensive computations on the Lua land and to avoid such computations from blocking the nginx event loop for too long. this feature requires OpenResty's delayed-posted-event patch for the nginx core. thanks Datong Sun for the patch.