Moke 最近频繁遭遇超时问题。经过一个多月的反复假设、测试、验证、以及用户反馈,我最终确定这不是 Moke 的问题,并且提取了最小可重现测试代码。
- 在正常发送 HTTP request、接收 response 一段时间后,某一个 request 会引发超时失败。此后一定时间内的所有 request 都会超时。
- 重启 app 可以解决;切换网络(WiFi <-> 3G)可以解决;关开网络(暂时启用飞行模式然后马上关闭飞行模式)可以解决。
应该是 HTTP persistent connection 的问题。当某一个 persistent connection 异常后,所有经由此 connection 发送的 request 都会超时。但这种异常并没有导致 persistent connection 中断,所以只要 request 之间的时间间隔不大于 keep alive 的时间长度,此 connection 还是会被一直继续复用,所以继续超时。
各种手动解决方案也反面证实是 persistent connection 的问题。因为所有解决方案之所以有效,都是因为它们迫使当前 persistent connection 中断后重现建立一个新的 connection。
- 请在代码中指定 access token。具体请阅读 Xcode 编译时的 warning。
- 测试时 app 必须在前台。
- 必须在日常用 iPhone 真机上进行。模拟器用的是 OS X 的网络层,和 iOS 网络层不一样,可能无法重现问题。问题发生的环境条件达成比较随机,专用测试设备的系统运行环境丰富度可能不够,所以请务必使用日常用机。
- 触发率很不稳定,但终会发生。连续运行了 10 分钟还没触发的话,切换到其他网络应用正常使用一段时间,再切换回来。过了很长时间还没触发的话,关闭后隔一段时间重新开始。请相信,终会发生。
- 问题发生后 app 会跳出警告,这是 app 中唯一显示的东西,其余信息都在 Xcode console logs 中。我设置了特殊断点,问题发生时 Xcode 会发出警告声音,所以无需一直盯着。有时超时错误是非连续的,这说明并没有进入目标问题状态。只有当超时错误连续发生时,才是我们要研究的问题状态。
可以确定的是这不是 Moke 的问题。无法确定这是微博开放平台服务器的问题,还是 iOS 系统的问题。但有了测试 app,新浪的 iOS 工程师和 server 工程师可以一起研究,定位问题根源。
代码很简单,只是每隔 10 秒钟调随机调用一个微博接口。大家可以移植到其他平台进行测试。如果其他平台也能重现问题,那就说明是微博开放平台服务器的问题。