0%

记一次rpc接口无返回调试经历

现象描述

偶然发现一个线上服务不返回的badcase,在输入特定一张图片时,分析服务会直接断开连接而不返回任何数据,这种情况是非常罕见的,因为通常来说即便是内部服务报错的情况下,也会被框架捕获从而返回一组错误码,而不会直接断开连接不返回任何数据。

初步分析

考虑到这个现象可以被特定数据触发,且触发后业务依旧可以正常处理后续请求,因此认为是业务逻辑的问题,但是还不清楚业务逻辑是如何影响框架导致连接被关闭的。

初步调试

现象能稳定复现,应该是比较容易调试的,我首先将一台线上服务熔断,手动登录后打开日志调试。

请求后惊奇的发现业务逻辑没有任何报错,由于业务逻辑不是我写的,所以整个逻辑对我来说如同黑箱一样。

为了找到问题的原因,我将一张正常图片产生的日志和问题图片产生的日志都记录下来,并逐行对比,遗憾的是没有发现任何不同

再次分析

到这一步已经是山穷水尽了,因为通过日志打点分析,整个业务逻辑是正常return的,现在只能将目光转向框架层,但是遗憾的是框架层同样是一个黑箱,并且通过分析框架层的日志,也没有发现任何异常。

结合连接直接断开的现象,我怀疑框架层中的worker在返回请求时崩溃,并且被自动重启了。而导致崩溃的原因,只能是在业务逻辑中返回的response结构体上。

大胆猜测,是返回值被设置了特殊值导致框架层崩溃的。

再次调试

将设置response的代码全部注释后,果然可以正常返回空结构体,确认了之前的猜测。

之后通过二分注释的方法,确认了问题出在一个float字段上,当float字段被设置为Nan时,会导致无返回的现象发生,至此问题确认。

总结

protobuf本身是支持nan作为值的,因此是框架层自己的兼容性问题,但是这种一言不合就暴毙的问题排查,着实令人头疼。