线上业务 coredump 是一件让工程师很紧张的事情,特别是每次崩溃都是出现在凌晨。我自己十几年前亲身经历过一次,当时为了定位这个只有凌晨才出现的“幽灵”bug,整个团队是下午回家睡觉,晚上 12 点到公司一起等待崩溃的现场,然后逐个服务来排查。想象一下,漆黑的夜晚和办公楼,只有几个工位亮着灯,守着屏幕上不断跳动的监控数据和日志,既紧张又刺激。我们守了三个晚上,才定位到bug并解决掉,这是难忘的一段经历。
没想到,这种经历又来了一次。只不过这次不是我们自己的服务,而是客户的线上服务出现了 coredump。这比我们自己完全可控的环境更有挑战:
-
只有线上业务发生错误,在预生产和测试环境都无法复现;
-
在开源的 Apache APISIX 基础上有自定代码,这部分代码在单独签署 NDA 之前看不到;
-
不能增加调试日志;
-
只在凌晨 3 点出现,需要调动客户更多资源才能即时处理。
也就是:没有复现方法,没有完整源代码,没有可以折腾的环境,但我们要定位原因,给出复现办法,并给出最终修复方案。期间有挑战有收获,在这里记录下解决问题过程中碰到的一些技术点,希望对大家排查 NGINX 和 APISIX 问题有借鉴。
问题描述
用户原来使用 APISIX 2.4.1 版本,没有出现问题,升级到 2.13.1 版本后,开始周期性出现 coredump,信息如下:
从 coredump 信息中能看出来 segmentation fault 发生在 lua-var-nginx-module 中。对应的内存数据(只粘贴了部分数据)如下:
#0 0x00000000005714d4 in ngx_http_lua_var_ffi_scheme (r=0x570d700, scheme=0x7fd2c241a760)
at /tmp/vua-openresty/openresty-1.19.3.1-build/openresty-1.19.3.1/../lua-var-nginx-module/src/ngx_http_lua_var_module.c:152
152 /tmp/vua-openresty/openresty-1.19.3.1-build/openresty-1.19.3.1/../lua-var-nginx-module/src/ngx_http_lua_var_module.c: No such file or directory.
(gdb) print *r
$1 = {signature = 0, connection = 0x0, ctx = 0x15, main_conf = 0x5adf690, srv_conf = 0x0, loc_conf = 0x0, read_event_handler = 0xe, write_event_handler = 0x5adf697,
cache = 0x2, upstream = 0x589c15, upstream_states = 0x0, pool = 0x0, header_in = 0xffffffffff