报错地方
lualib/resty/redis.lua:101: API disabled in the context of init_worker_by_lua*
stack traceback:
[C]: in function 'tcp'
.../lualib/resty/redis.lua:101: in function 'new'
现在有个需求,需要在worker中起个定时器定时从redis中获取数据刷新到本地缓存中,但我在init模块中调用resty-redis api时,提示api disabled,请问该如何实现 --
报错地方lualib/resty/redis.lua:101: API disabled in the context of init_worker_by_lua*stack traceback: [C]: in function 'tcp' .../lualib/resty/redis.lua:101: in function 'new'在 2016年1月16日 下午12:29,L.D <dongxin...@gmail.com>写道:现在有个需求,需要在worker中起个定时器定时从redis中获取数据刷新到本地缓存中,但我在init模块中调用resty-redis api时,提示api disabled,请问该如何实现 --
redis.new()放在定时器回调方法内在 2016年1月16日星期六 UTC+8下午1:07:14,L.D写道: 报错地方lualib/resty/redis.lua:101: API disabled in the context of init_worker_by_lua*stack traceback: [C]: in function 'tcp' .../lualib/resty/redis.lua:101: in function 'new'在 2016年1月16日 下午12:29,L.D <dongxin...@gmail.com>写道:现在有个需求,需要在worker中起个定时器定时从redis中获取数据刷新到本地缓存中,但我在init模块中调用resty-redis api时,提示api disabled,请问该如何实现 --
hi,我刚试了下,可以了,谢谢~在 2016年1月16日星期六 UTC+8下午3:01:49,humphery写道:redis.new()放在定时器回调方法内在 2016年1月16日星期六 UTC+8下午1:07:14,L.D写道: 报错地方lualib/resty/redis.lua:101: API disabled in the context of init_worker_by_lua*stack traceback: [C]: in function 'tcp' .../lualib/resty/redis.lua:101: in function 'new'在 2016年1月16日 下午12:29,L.D <dongxin...@gmail.com>写道:现在有个需求,需要在worker中起个定时器定时从redis中获取数据刷新到本地缓存中,但我在init模块中调用resty-redis api时,提示api disabled,请问该如何实现 --
哥们,你的使用定时器的时候,每个worker都会起来一个timer,你有没有做锁?是怎么保证只启动一个timer的?其实我的场景和你一样,都是需要从redis更新到lua shared dict 。
应用场景
整个 openresty 启动后,我们有时候需要后台处理某些动作,比如数据定期清理、同步数据等。而这个后台任务实例我们期望是唯一并且安全,这里的安全指的是所有 nginx worker 任意 crash 任何一个,有机制合理保证后续 timer 依然可以正常工作。
这里需要给大家介绍一个重要 API ngx.worker.id() 。
语法: seq_id = ngx.worker.id() 返回当前 Nginx 工作进程的一个顺序数字(从 0 开始)。 所以,如果工作进程总数是 N,那么该方法将返回 0 和 N - 1 (包含)的一个数字。 该方法只对 Nginx 1.9.1+ 版本返回有意义的值。更早版本的 nginx,将总是返回 nil 。
解决办法
通过 API 描述可以看到,我们可以用它来确定这个 worker 的内部身份,并且这个身份是相对稳定的。即使当前 nginx 进程因为某些原因 crash 了,新 fork 出来的 nginx worker 是会继承这个 worker id 的。
剩下的问题就比较简单了,完全可以把我们的 timer 绑定到某个特定的 worker 上即可。
init_worker_by_lua ' local delay = 3 -- 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 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 ';
在 2016年1月15日星期五 UTC-8下午11:32:26,L.D写道:hi,我刚试了下,可以了,谢谢~在 2016年1月16日星期六 UTC+8下午3:01:49,humphery写道:redis.new()放在定时器回调方法内在 2016年1月16日星期六 UTC+8下午1:07:14,L.D写道: 报错地方lualib/resty/redis.lua:101: API disabled in the context of init_worker_by_lua*stack traceback: [C]: in function 'tcp' .../lualib/resty/redis.lua:101: in function 'new'在 2016年1月16日 下午12:29,L.D <dongxin...@gmail.com>写道:现在有个需求,需要在worker中起个定时器定时从redis中获取数据刷新到本地缓存中,但我在init模块中调用resty-redis api时,提示api disabled,请问该如何实现 -- --
2016-08-08 18:18 GMT+08:00 wwaz wwaz <3824...@qq.com>:哥们,你的使用定时器的时候,每个worker都会起来一个timer,你有没有做锁?是怎么保证只启动一个timer的?其实我的场景和你一样,都是需要从redis更新到lua shared dict 。 可以看看这里:https://github.com/moonbingbing/openresty-best-practices/blob/master/ngx_lua/how_one_instance_time.md应用场景整个 openresty 启动后,我们有时候需要后台处理某些动作,比如数据定期清理、同步数据等。而这个后台任务实例我们期望是唯一并且安全,这里的安全指的是所有 nginx worker 任意 crash 任何一个,有机制合理保证后续 timer 依然可以正常工作。这里需要给大家介绍一个重要 API ngx.worker.id() 。语法: seq_id = ngx.worker.id() 返回当前 Nginx 工作进程的一个顺序数字(从 0 开始)。 所以,如果工作进程总数是 N,那么该方法将返回 0 和 N - 1 (包含)的一个数字。 该方法只对 Nginx 1.9.1+ 版本返回有意义的值。更早版本的 nginx,将总是返回 nil 。 解决办法通过 API 描述可以看到,我们可以用它来确定这个 worker 的内部身份,并且这个身份是相对稳定的。即使当前 nginx 进程因为某些原因 crash 了,新 fork 出来的 nginx worker 是会继承这个 worker id 的。剩下的问题就比较简单了,完全可以把我们的 timer 绑定到某个特定的 worker 上即可。init_worker_by_lua ' local delay = 3 -- 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 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 '; 在 2016年1月15日星期五 UTC-8下午11:32:26,L.D写道:hi,我刚试了下,可以了,谢谢~在 2016年1月16日星期六 UTC+8下午3:01:49,humphery写道:redis.new()放在定时器回调方法内在 2016年1月16日星期六 UTC+8下午1:07:14,L.D写道: 报错地方lualib/resty/redis.lua:101: API disabled in the context of init_worker_by_lua*stack traceback: [C]: in function 'tcp' .../lualib/resty/redis.lua:101: in function 'new'在 2016年1月16日 下午12:29,L.D <dongxin...@gmail.com>写道:现在有个需求,需要在worker中起个定时器定时从redis中获取数据刷新到本地缓存中,但我在init模块中调用resty-redis api时,提示api disabled,请问该如何实现 -- -- -- YuanSheng Wang---------------------------------------My Github: https://github.com/membphisOpenResty lover ^_^
使得,worker.id可以达到要求,但是只在nginx.1.9.++支持。我用的tengine,是否有类似的API呢?绑定某一个进程的。。
在 2016年8月8日星期一 UTC-4上午10:49:58,YuanSheng写道:2016-08-08 18:18 GMT+08:00 wwaz wwaz <3824...@qq.com>:哥们,你的使用定时器的时候,每个worker都会起来一个timer,你有没有做锁?是怎么保证只启动一个timer的?其实我的场景和你一样,都是需要从redis更新到lua shared dict 。 可以看看这里:https://github.com/moonbingbing/openresty-best-practices/blob/master/ngx_lua/how_one_instance_time.md应用场景整个 openresty 启动后,我们有时候需要后台处理某些动作,比如数据定期清理、同步数据等。而这个后台任务实例我们期望是唯一并且安全,这里的安全指的是所有 nginx worker 任意 crash 任何一个,有机制合理保证后续 timer 依然可以正常工作。这里需要给大家介绍一个重要 API ngx.worker.id() 。语法: seq_id = ngx.worker.id() 返回当前 Nginx 工作进程的一个顺序数字(从 0 开始)。 所以,如果工作进程总数是 N,那么该方法将返回 0 和 N - 1 (包含)的一个数字。 该方法只对 Nginx 1.9.1+ 版本返回有意义的值。更早版本的 nginx,将总是返回 nil 。 解决办法通过 API 描述可以看到,我们可以用它来确定这个 worker 的内部身份,并且这个身份是相对稳定的。即使当前 nginx 进程因为某些原因 crash 了,新 fork 出来的 nginx worker 是会继承这个 worker id 的。剩下的问题就比较简单了,完全可以把我们的 timer 绑定到某个特定的 worker 上即可。init_worker_by_lua ' local delay = 3 -- 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 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 '; 在 2016年1月15日星期五 UTC-8下午11:32:26,L.D写道:hi,我刚试了下,可以了,谢谢~在 2016年1月16日星期六 UTC+8下午3:01:49,humphery写道:redis.new()放在定时器回调方法内在 2016年1月16日星期六 UTC+8下午1:07:14,L.D写道: 报错地方lualib/resty/redis.lua:101: API disabled in the context of init_worker_by_lua*stack traceback: [C]: in function 'tcp' .../lualib/resty/redis.lua:101: in function 'new'在 2016年1月16日 下午12:29,L.D <dongxin...@gmail.com>写道:现在有个需求,需要在worker中起个定时器定时从redis中获取数据刷新到本地缓存中,但我在init模块中调用resty-redis api时,提示api disabled,请问该如何实现 -- -- -- YuanSheng Wang---------------------------------------My Github: https://github.com/membphisOpenResty lover ^_^ --
2016-08-08 22:56 GMT+08:00 wwaz wwaz <3824...@qq.com>:使得,worker.id可以达到要求,但是只在nginx.1.9.++支持。我用的tengine,是否有类似的API呢?绑定某一个进程的。。看来是时候考虑全线迁移到 openresty 了,它太久不往前发展,停顿了。 其他绕路方式,都没有上面的例子简单、直接,lua-resty-lock + 一些业务逻辑,可以试试,要写很多冗余代码。在 2016年8月8日星期一 UTC-4上午10:49:58,YuanSheng写道:2016-08-08 18:18 GMT+08:00 wwaz wwaz <3824...@qq.com>:哥们,你的使用定时器的时候,每个worker都会起来一个timer,你有没有做锁?是怎么保证只启动一个timer的?其实我的场景和你一样,都是需要从redis更新到lua shared dict 。 可以看看这里:https://github.com/moonbingbing/openresty-best-practices/blob/master/ngx_lua/how_one_instance_time.md应用场景整个 openresty 启动后,我们有时候需要后台处理某些动作,比如数据定期清理、同步数据等。而这个后台任务实例我们期望是唯一并且安全,这里的安全指的是所有 nginx worker 任意 crash 任何一个,有机制合理保证后续 timer 依然可以正常工作。这里需要给大家介绍一个重要 API ngx.worker.id() 。语法: seq_id = ngx.worker.id() 返回当前 Nginx 工作进程的一个顺序数字(从 0 开始)。 所以,如果工作进程总数是 N,那么该方法将返回 0 和 N - 1 (包含)的一个数字。 该方法只对 Nginx 1.9.1+ 版本返回有意义的值。更早版本的 nginx,将总是返回 nil 。 解决办法通过 API 描述可以看到,我们可以用它来确定这个 worker 的内部身份,并且这个身份是相对稳定的。即使当前 nginx 进程因为某些原因 crash 了,新 fork 出来的 nginx worker 是会继承这个 worker id 的。剩下的问题就比较简单了,完全可以把我们的 timer 绑定到某个特定的 worker 上即可。init_worker_by_lua ' local delay = 3 -- 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 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 '; 在 2016年1月15日星期五 UTC-8下午11:32:26,L.D写道:hi,我刚试了下,可以了,谢谢~在 2016年1月16日星期六 UTC+8下午3:01:49,humphery写道:redis.new()放在定时器回调方法内在 2016年1月16日星期六 UTC+8下午1:07:14,L.D写道: 报错地方lualib/resty/redis.lua:101: API disabled in the context of init_worker_by_lua*stack traceback: [C]: in function 'tcp' .../lualib/resty/redis.lua:101: in function 'new'在 2016年1月16日 下午12:29,L.D <dongxin...@gmail.com>写道:现在有个需求,需要在worker中起个定时器定时从redis中获取数据刷新到本地缓存中,但我在init模块中调用resty-redis api时,提示api disabled,请问该如何实现 -- -- -- YuanSheng Wang---------------------------------------My Github: https://github.com/membphisOpenResty lover ^_^ -- -- YuanSheng Wang---------------------------------------My Github: https://github.com/membphisOpenResty lover ^_^
嗯,谢谢yuansheng,其实我也想迁到OR上去,省事方便许多。但是公司现在用的是tengine,迁移成本估计有点大。360是用的OR么?还是nginx+ngx_lua?我用lua-resty-lock来试试看。在 2016年8月8日星期一 UTC-7上午8:07:10,YuanSheng写道:2016-08-08 22:56 GMT+08:00 wwaz wwaz <3824...@qq.com>:使得,worker.id可以达到要求,但是只在nginx.1.9.++支持。我用的tengine,是否有类似的API呢?绑定某一个进程的。。看来是时候考虑全线迁移到 openresty 了,它太久不往前发展,停顿了。 其他绕路方式,都没有上面的例子简单、直接,lua-resty-lock + 一些业务逻辑,可以试试,要写很多冗余代码。在 2016年8月8日星期一 UTC-4上午10:49:58,YuanSheng写道:2016-08-08 18:18 GMT+08:00 wwaz wwaz <3824...@qq.com>:哥们,你的使用定时器的时候,每个worker都会起来一个timer,你有没有做锁?是怎么保证只启动一个timer的?其实我的场景和你一样,都是需要从redis更新到lua shared dict 。 可以看看这里:https://github.com/moonbingbing/openresty-best-practices/blob/master/ngx_lua/how_one_instance_time.md应用场景整个 openresty 启动后,我们有时候需要后台处理某些动作,比如数据定期清理、同步数据等。而这个后台任务实例我们期望是唯一并且安全,这里的安全指的是所有 nginx worker 任意 crash 任何一个,有机制合理保证后续 timer 依然可以正常工作。这里需要给大家介绍一个重要 API ngx.worker.id() 。语法: seq_id = ngx.worker.id() 返回当前 Nginx 工作进程的一个顺序数字(从 0 开始)。 所以,如果工作进程总数是 N,那么该方法将返回 0 和 N - 1 (包含)的一个数字。 该方法只对 Nginx 1.9.1+ 版本返回有意义的值。更早版本的 nginx,将总是返回 nil 。 解决办法通过 API 描述可以看到,我们可以用它来确定这个 worker 的内部身份,并且这个身份是相对稳定的。即使当前 nginx 进程因为某些原因 crash 了,新 fork 出来的 nginx worker 是会继承这个 worker id 的。剩下的问题就比较简单了,完全可以把我们的 timer 绑定到某个特定的 worker 上即可。init_worker_by_lua ' local delay = 3 -- 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 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 '; 在 2016年1月15日星期五 UTC-8下午11:32:26,L.D写道:hi,我刚试了下,可以了,谢谢~在 2016年1月16日星期六 UTC+8下午3:01:49,humphery写道:redis.new()放在定时器回调方法内在 2016年1月16日星期六 UTC+8下午1:07:14,L.D写道: 报错地方lualib/resty/redis.lua:101: API disabled in the context of init_worker_by_lua*stack traceback: [C]: in function 'tcp' .../lualib/resty/redis.lua:101: in function 'new'在 2016年1月16日 下午12:29,L.D <dongxin...@gmail.com>写道:现在有个需求,需要在worker中起个定时器定时从redis中获取数据刷新到本地缓存中,但我在init模块中调用resty-redis api时,提示api disabled,请问该如何实现 -- -- -- YuanSheng Wang---------------------------------------My Github: https://github.com/membphisOpenResty lover ^_^ -- -- YuanSheng Wang---------------------------------------My Github: https://github.com/membphisOpenResty lover ^_^ --