记一次怪异的bug,和debug的思路---测试环境才有的代码请求了线上环境


发现问题

美好的周五下午,QA突然说收到报警邮件,一个接口线上报错,并且持续半小时了,报错的请求的参数来自同一个参数号
咋回事呢?我们马上看看

理清楚背景,这个问题似乎不太可能发生

这个报错类型的接口,通过参数看出来自于渠道A,但是渠道A的前端代码现在只发布了测试环境(难道是请求后端接口时候,环境搞错了)。
并且报错的请求的那个参数,正是我们的开发此项目,留在项目公开备注的参数。(是不是有其他同事在用这个示例参数轮询)

尝试解决问题

首先,我们在开发群里问了下大家,是谁在用备注的参数轮询请求线上接口,快出来,我们保证不打你
群里没人回应,排除这个原因

然后,我们去仔细分析接口报错的原因,发现是因为接口请求没能解析登录信息,导致的报错,并且调用这个接口的逻辑,是一次请求失败,就会开始轮询,直到请求成功。正常情况下用户在app内肯定是已经登录的状态,并且也不会有这个页面的入口。所以我们考虑是不是内部的同事没有登录,打开了这个页面。
我们顺着这个请求,查到trace,查看前端直接请求restful层的请求头,real-ip查到,是个内网ip!
哈哈,基本确定是同事在搞鬼了。
不对同事是打不开这个页面的线上链接的,因为还没有发布线上,如果打开的是测试环境的页面,那怎么会请求到线上环境呢?
哦豁,这个问题看似不太可能发生

接下来,我们继续用netstat命令,想根据ip反查计算机名,没有查到。
那就再接着分析请求头,看到了ua,我去,user-agent居然是axios/0.18.1,啊,怎么会是这个?
我们去看了下项目里面依赖的axios版本,正是0.18.1版本。基本说明正是项目发出的请求,打到了线上,
马上登录到项目测试环境的服务器上一看IP,正是那个内网IP,确认了,就是测试环境的项目,发出来请求到线上,导致了报错。

继续探索,我们看了下请求接口的封装,是调用了公共方法,不可能有环境请求错的问题。
那怎么会请求到线上呢?
于是我们再测试环境,清除登录信息,传入另外一个参数来模拟测试,一查日志,果然,另外一个参数也马上出现在了报错里面,
问题复现了,哈哈哈,我真牛逼!!!
不对,那为什么会从测试环境请求到了线上呀,接口也没有转发,是直接请求的呀,不会吧不会吧!
对了,上面提到了User-Agent,正常请求UA应该是app或者浏览器的UA才对呀,怎么会是axios/版本号呢?

去axios的GitHub里看了下issue,果然发现了,有人提到在node环境,请求失败的User-Agent会变成这个格式!
我去,我们的接口没有过node环境啊,是直接请求的后端的restful层啊,这就tmd离谱!!!

理性分析

结合上面的线索,理性思考,我们的请求有可能从node发出吗?
从node发出的话,有可能去请求线上接口吗?
真相只有一个
去看代码,1s就确认了

得出答案
我们的项目是基于next.js开发的,也就是使用的服务端渲染。
而这个接口的请求,没错,写在了constructor里面,所以会在服务端请求(axios支持服务端请求)。
因为node端拿不到登录信息,所以会报错,请求失败,并且一直请求。
因为node环境在公共的请求接口方法里面判断不了环境,所以默认请求了线上环境。

破案。
PS:next.js的官方文档做得感觉很不好,连生命周期都没有讲清楚。远不如nuxt.js。具体生命周期可以参照这张图

待补充一点体会,和总结

声明:高翔的博客|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 记一次怪异的bug,和debug的思路---测试环境才有的代码请求了线上环境


高翔的博客