一、背景
图片加载作为重中之重的App体验指标,端侧的白屏问题则是其中最为严重的问题之一。想象一下如果你在浏览交易商品、社区帖子等核心场景下,图片无法完成加载是多么糟糕的体验。
网络作为图片资源加载的最主要来源途径,如果不能够快速的响应请求,那对上层图片库而言,就是巧妇难为无米之炊了。
而且,通过线上白屏问题归因,我们看到网络问题导致比例最高,占比达81.97%。除去常见的弱网/无网等问题外,还有很多各种各样的网络环境问题我们是可以进行优化的,例如设备不支持IPv6,CDN节点异常,证书超时等。
二、网络优化&监控概览
网络优化与监控体系
三、网络监控能力
网络异常导致的图片白屏问题,往往和当时的环境有关,例如用户连的WIFI不支持IPv6但是DNS返回的大部分是V6的IP等,此时仅靠几条带有SocketTimeoutException的网络日志根本无法排查出问题的根因,就如同ANR问题需要火焰图一样,白屏问题同样需要一套完善的监控体系来记录问题现场的信息,从而分析问题根因。
OkHttp基础监控
图片网络请求的阶段信息,可以通过实现OkHttp自带的EventListener来获取,在各个阶段开始和结束点记录下时间戳即可。
其中需要重点关注connectFailed,requestFailed和responseFailed这三个失败的回调,他们都会在失败之后重试,并重复执行阶段开始的回调(例如connectStart),因此针对这些需要单独记录好每一次失败信息,避免被覆盖。
例:某个图片请求TCP建连失败的记录
APM流量监控
尽管我们有专门的网络诊断工具,但是考虑到网络异常的滞后性,故障往往是数十秒之前引入的(例如进电梯弱网),而发生问题之后才触发的网络诊断结果仅能作为参考,并不能作为最终问题归因的证据。
因此我们需要一个更直观的表达用户设备网络状况的数据,那就是通过系统API获取的当前App流量消耗,在排除了一些本地socket通信产生的干扰之后,最近N秒之内消耗的流量/N就可以认为是白屏问题发生时的网速。
我们以3秒为间隔分段计算并取最大值来排除波动,这样我们就得到了白屏问题发生前一段时间内的网速状态,过低的就可以判定为弱网/无网。
网速计算示意图:
CDN异常记录
CDN厂商侧的异常,例如服务器IP跨省,节点挂了等问题相对少见,在网络日志中通常就表现为建连超时但是网络正常,因此需要收集多个Host的请求记录进行横向对比来确认是单个CDN厂商的问题。
为此我们记录了主站接口的域名,以及所有CDN域名在最近N分钟内的请求统计,包括了正常请求、慢请求、失败请求的数量和原因,以及失败请求使用的具体IP。
例:图中可以看到某CDN的请求全部都是建连失败,而其他CDN以及我们主站域名请求均正常,那么此问题可以归类为该CDN的单点问题,联系CDN服务商剔除该IP所在节点即可解决问题。
网络库请求缓存
常规的网络监控方案为了节省内存,会在请求结束时将其从内存缓存队列中移除,而白屏问题因为其滞后性,只有在屏幕中大面积出现白图才会被判定,此时再去查询加载失败的图片网络请求日志自然早已被移出队列,因此需要单独使用一个LRU队列来缓存最近N条网络日志,图片库同理。
网络诊断工具
在逐步解决用户问题的过程中,我们研发了网络诊断工具,实现了基础网络信息采集、Ping、TraceRoute等。
当检测到用户发生白屏时自动触发网络诊断。
单域名诊断流程
我们会依次进行DNS、Http、Ping(ICPM)与Ping(TCP)、TraceRoute诊断。如果是双栈客户端(同时返回了IPv4与IPv6),那么我们会选择首个IPv4与首个IPv6同时进行Ping/TraceRoute以确认不同IP类型的联通情况。
多域名诊断流程
同时对3个得物核心域名发起诊断。为了辅助判断,当得物核心域名诊断失败时,也会对一些主流三方域名稍微Ping一下。
诊断数据的上报
由于网络诊断可能耗时10秒以上,而如此长的时间内用户如果退出App那我们的诊断数据可能就丢失了。因此,任意一个小阶段的诊断完成时,我们就立即上报此结果,以避免此类情况的发生。
四、CDN质量监控
CDN作为整体白屏问题中重要的一环。在白屏排查过程中,经常遇到接口正常,但CDN访问异常的case。而多云CDN的质量问题往往依赖于云厂商,如何衡量和监控云厂商的CDN情况成为了关键,故我们自定义了端侧的CDN质量指标体系以及配合云厂商推进云端策略的优化。