【1】问题现象
(1)本地openresty系统
(2)报错信息
2019/09/10 08:13:55 [error] 2385#2385: *4 lua entry thread aborted: runtime error: /usr/local/lib/ubcservd/bin/../work/bill_timer.lua:1647: attempt to concatenate global 'value' (a nil value)
(3)分析原因
value变量为nil值的场景预先没有考虑到,导致连接字符串时失败。
(4)解决(容错)方案
打印value值时,增加nil值的判断。如下:
ngx.log(ngx.ERR, 'todo and print value: ' .. (value or 'nil'))
【2】问题追思
如上异常,出现过"lua entry thread aborted"以后,这个worker process(即id为2385)到底还存活吗?
注意,这里所谓的存活是相对于C++程序的空指针导致应用程序异常崩溃而言。
模拟场景,分析过程如下:
(1)具体思路:
设计两个定时器,分别设置不同的时间间隔(第一个时间间隔120s短于第二个180s),启动nginx系统:
当第一个定时器执行异常(如上错误)后,观察第二个定时器是否可以正常执行。
(2)源码如下:
[1] 配置文件:
nginx.conf,如下:
worker_processes ; user root; events { worker_connections ; } http { default_type application/octet-stream; sendfile on; send_timeout ; keepalive_timeout ; lua_package_path "/usr/local/lib/ubcservd/lualib/?.lua;;"; lua_package_cpath "/usr/local/lib/ubcservd/lualib/?.so;;"; init_worker_by_lua_file work/bill_timer.lua; }
[2] 定时器文件:
bill_timer.lua,如下:
local new_timer = ngx.timer.at local function timer_test_one(permature) if not premature then ngx.log(ngx.ERR, "into timer_test_one print value " .. value) , timer_test) if not ok then ngx.log(ngx.ERR, "failed to create timer_test_one timer : ", err) else ngx.log(ngx.ERR, ') end end end local function timer_test_two(permature) if not premature then ngx.log(ngx.ERR, "into timer_test_two print ") , timer_test_two) if not ok then ngx.log(ngx.ERR, "failed to create timer_test_two timer : ", err) else ngx.log(ngx.ERR, ') end end end == ngx.worker.id() then , timer_test_one) if not ok then ngx.log(ngx.ERR, "failed to create timer_test_one timer : " .. err) else ngx.log(ngx.ERR, ') end , timer_test_two) if not ok then ngx.log(ngx.ERR, "failed to create timer_test_two timer : " .. err) else ngx.log(ngx.ERR, ') end end
[3] 启动nginx系统
成功启动,创建3个worker process,如下图:
[4] 日志分析
第一个定时器执行异常中止错误信息,立即观察worker进程情况:
进程id值为2869仍然存在,安然无恙。
第二个定时器执行正常打印信息,所有日志,如下图:
综上所述:“thread aborted” 并非崩溃,仅仅只是当前函数执行失败中止,此函数其余语句不会再执行。
Good Good Study, Day Day Up.
顺序 选择 循环 总结