一、前言

于2024年7月8号下午16:12分,也就是昨天下午线上业务反馈异常,同一时间,业务也出现了告警,官网访问“502 Bad Gateway”,随后便介入展开排查。附上官网截图

记一次因Nginx正则表达式导致官网门户故障案例_Nginx

二、排查过程

看报错反馈,因为我们的负载入口是走的阿里云SLB,后面代理了两台Nginx服务器作为高可用环境,我第一时间登录阿里云负载均衡器检查代理的后端服务器所监听状态,果然不出我所料,SLB后端监听代理的服务器异常

记一次因Nginx正则表达式导致官网门户故障案例_nginx_02

此时,我想到的是nginx服务异常,导致阿里云负载均衡健康检测无法正常访问,于是乎,我立即到SLB对应的两台Nginx节点,检查Nginx服务状态是否异常,结果发现进程虽然正常启动,但是时间保持在"00:00:00"状态.

记一次因Nginx正则表达式导致官网门户故障案例_nginx_03

阿里云SLB负载均衡有一个健康尝试curl下健康关联的健康检测文件,发现直接返回404,随后排查了匹配文件都是存在的。不会出现健康检查文件被误删的情况,导致该问题出现。

记一次因Nginx正则表达式导致官网门户故障案例_Nginx_04

#curl x.x.x.x/xxx.html #本地测试nginx节点健康检测文件是否正常

记一次因Nginx正则表达式导致官网门户故障案例_Nginx_05

于是回顾下午对生产nginx做了配置变更,确定时间线,为了缩短故障时间,减少影响程度,立马回滚了下午变更的配置文件,便对下午问题进行配置回滚将该配置取消,让Nginx重载,最终故障得以恢复正常。下面给出罪魁祸首截图(Ps:细微之处导致问题出现,一般人真的很难看出来 )

记一次因Nginx正则表达式导致官网门户故障案例_nginx_06

location ~ ^(/ecp_html/|/ecp_pdf/|/ecp_word/|/ecp_image/|/ecp_fl_original_file/|/ecp_fl_original_html/|/ecp_contract_accessory_file/|/ecp_contract_edited_html/|/ecp_fl_original_pdf/|) {
proxy_pass http://x.x.x.x.aliyuncs.com; #阿里云OSS对象存储地址
}

三、原因分析

3.1.事故前因后果

   研发提出新增Nginx location配置需求,要在原基础上新增一个Localtion规则,对OSS对象存储访问,因新增配置过程中Location配置文件多出了一个"|"管道符Nginx服务失效,因该节点涉及到整个负载流量均衡入口,最终影响整个门生产环境用户访问

  3.2. 为什么会出现这个问题?

   上述Nginx配置规则存在问题,问题在于正则表达式末尾多出来一个管道符号“|”,一般来说在正则表达式中,“|”管道符号是用于分隔多个匹配选项,然而,问题在于正则表达式末尾多出一个“|”,这是的正则表达式不在完整,Nginx自然就无法正确解析该规则。

  3.3.为什么配置完毕自检无异常?

   Nginx在检查配置文件(使用nginx -t命令)时,并不会对正则表达式语法错误进行详尽检查,尤其是对于语法的细微错误,可能不会立即报错,这可能导致及时有一些问题存在,Nginx仍然会成功加载配置文件,但实际上该配置并不会按照预期工作,总的来说在最后一个选项/ecp_fl_original_pdf/|)中,末尾多出了一个|符号,这不是有效的正则表达式语法。nginx在检查配置文件时,可能会忽略这种细微的语法错误,因此Nginx -t自检并不会报错。

四、问题总结

尽管nginx -t命令可能没有报告语法错误,但实际上配置文件中的正则表达式语法错误会影响到nginx的实际工作。因此,确保配置文件中的正则表达式语法是正确的非常重要,特别是在涉及到复杂或长的匹配规则时。修正你的配置后,再次使用nginx -t命令确认是否正确。总结一句话:细节决定成败!运维这个岗位真的是细腻活,多一个空格、少一个空格,多一个字符串、少一个字符串,不经意间真的可能会造成意想不到的后果。一失足成年古恨。好啦,我继续反思了....