RCA:收单设备调用云端接口频繁超时排查总结
研发中心/王鹏 2019年7月
关键词:okhttp,安卓,连接复用,开源软件bug
一.背景知识:
okhttp已是安卓项目中被广泛使用的网络请求开源库,它有如下特性:
1.支持http/2,允许所有同一个主机地址的请求共享同一个socket连接;
2.连接池减少请求延时;
3.缓存响应内容,避免一些完全重复的请求;
4.透明的gzip压缩减少响应数据的大小;
其中前三点特性可理解为就是连接复用,但后来发现这里有坑~
二.问题现象:
据现场端反馈,即使在网络正常的情况下,也会有个别设备会在某个时段内出现支付缓慢,多笔交易连续失败的情况。
通过业务保障平台发现订单查询接口一直出现sockettimeoutexception。
三.问题原因:
如果okhttp第一次出现sockettimeoutexception,后续即使网络已经恢复正常,请求也始终返回sockettimeoutexception,必须等到双活域名切换或者重新连接wifi,或重新启动应用程序才能恢复正常。
四.排查过程:
根据以上日志分析,可发现一个规律:切换(双活机房)基础域名时,请求便恢复正常,基本符合okhttp源码中不复用之前连接的条件:
所以我初步怀疑这是连接复用的特性导致的:
即问题出现之后,一直在复用错误的连接,而域名切换之后,不再复用之前的错误连接,于是请求恢复正常。
但项目中的连接池复用一直采用的是okhttp默认设置的配置,未做其他改动,所以怀疑okhttp有bug。
查看okhttp github的issues,发现2019年4月26号新增了一条issues,与我们的问题类似。问题如下:
内容大致意思为:部分设备出现了sockettimeout后,后续请求一直返回sockettimeout,尤其是在4g网络下比较常见!目前该问题仍未解决,处于开放状态,bug依旧存在。
五.解决方法:
在全局 responseerror 监听器里,如果发现出现 sockettimeout 就清空连接池:
目前此方案的缺点是应用程序出现sockettimeout一次,下一次访问才能成功,当前请求无法修正。
后续会持续关注此issues修复状态,及时更新。
七.经验教训:
1.使用第三方开源库,一定要熟悉其原理,在使用前一定要通篇了解其issues中反馈的各种问题,评估其影响,平常定期不定期关注其issues更新。p.s.:郑总的《》,已给我们打过预防针了。
2.做好边界测试和压力测试。
3.一定要重视线上问题,明确根本原因并评估其影响。之前惯性地认为sockettimeout就是网络状况不好导致的,未引起足够重视。
八.rca类型:
开源软件的bug
-eof-
欢迎关注公众号:老兵笔记,讲述那些年我们一起犯过的错
上一篇: 触控变身更强续航 超级旅行“本”就不同
下一篇: Go调用Delphi编写的DLL