记一次一个枚举引发线上事故风暴

背景

  2018年8月15号下午6点左右一个我们服务的调用方通知我们他们在调用服务接口时出现了大量的异常和通知,并且错误返回值都是“显示未设置结束日期”

问题定位

收到调用方的消息后,我立即展开了问题的排查

1、通过服务管理平台查看服务是否出现超时及比对今天和昨天接口整体的响应时长,但是排查后发现服务正常。

2、通过调用方提供异常用户id从日志中排查是否出现异常,排查发现日志中也打印了未设置结束日期的错误信息,但是还是无法定位问题原因

3、根据调用方提供的返回值信息在项目工程中进行全局搜索,发现这个返回枚举值除了在添加接口引用并没有其他接口在引用,此时我就非常纳闷为什么这个接口没有引入这个枚举日志中却显示了这个枚举值呢。

4、通过上面的情况我想是不是枚举填充错位或者被攻击了,为了证明猜想我在本地写了一个程序来调用线上服务,发现返回的结果值是正确的,说明服务是正常的,然后又让调用方按照我的方式继续调用线上服务,奇怪的是当他们已调用服务这个异常信息就被打印出来

5、这个问题我们已经连续排查第二天的凌晨但是依然找不到原因,最后我们就想重启下试试,也可能是某个内存或者环境出问题了,我们重启了其中2台机器,并将这两台分组给调用方,结果调用方正常了,正当准备回家睡觉然后明天在继续跟踪问题的时候发现那个异常又在次出现

6、最后一个同事不经意说是不是有人篡改了枚举值,我们恍然大悟,立即看这个枚举是否能被set,果不其然有一个public的set值,然后我们搜索项目中有一个接口分支调用了这个set值

7、问题基本都已经定位完毕,引发这个bug是同事在6点刚好上线,他们在添加时候没有传入日期导致了bug被复现

解决方案

我们删除了set这段代码,然后采用返回实体,线下验证正常后进行上线,上线后问题业务方的调用恢复正常。

附加前后2种代码对比:

后续规避

1、定义部门中的相关规划(如禁止枚举开放set值)

2、加强代码review,重要的项目保证2个人同时开发,避免问题的产生

 

posted @ 2018-08-16 16:39  朝向远方  阅读(1067)  评论(6编辑  收藏  举报