大厂技术分享:网易新闻 QUIC 敏捷实践( 二 )


大厂技术分享:网易新闻 QUIC 敏捷实践

文章插图
图5 QUIC拦截器处理
而对于下层的默认拦截器和自定义网络拦截器都将被 QUIC 短路,默认拦截器中主要提供了缓存、Gzip 解压、建联等处理,其中一部分处理策略由 Cronet 也可以替代实现,而重定向一类策略在 Cronet 监听回调中处理也较为便利 。
使用 Cronet 发起请求提供两种实现,一种是 CronetUrlRequest,另一种是符合 HttpURLConnection 标准的,在 CronetUrlRequest 基础上封装了流操作的 CronetHttpURLConnection,由于客户端涉及多媒体场景较多,使用 CronetHttpURLConnection 更能满足大部分需求场景 。
目前,我们在视频、图集、列表通用业务网络请求等范围全面实现了 QUIC 的接入 。
2.3.1.2 数据衡量
为了更明显地对比出 QUIC 与 HTTP/HTTPS 之间的数据变化,我们使用了两套网络数据监测机制:全链路统计和 APM ,以精准捕获特定请求事件的时间戳,来计算并上报建联时间、响应时间等信息 。
通过 Cronet 提供的一些回调,可以实现与 OKHttp 上报监听的逻辑统一 。Cronet 提供的 RequestFinishedInfo 可以获得 Request 的建联等信息,提供的 UrlRequest.Callback 可以获得响应等信息,而使用 RequestFinishedInfo 会增加一部分监控逻辑,对 Cronet 有轻微的性能折损,仅使用 UrlRequest.Callback 返回的部分响应信息也足够得出 QUIC 性能数据,全链路上报 OKHttp 与 Cronet 监听对齐方案如 图6 所示 。
大厂技术分享:网易新闻 QUIC 敏捷实践

文章插图
图6 全链路上报事件
由于 Android Cronet 的 CronetHttpURLConnection 在设计上较为封闭,扩展性并不是十分良好,比如响应回调 UrlRequest.Callback,或是内部实现的阻塞队列控制 MessageLooper 都没有暴露给开发者,在此基础上定制一些功能实现,如全链路上报,或是 CronetHttpURLConnection 没有提供的超时时间策略,都不是很方便 。
为了解决这个问题,我们建立了一层代理和装饰器,通过拦截 CronetEngine 可以拿到 CronetHttpURLConnection 的 UrlRequest.Callback,对此再做一层包装,由包装类进行统一的事件分发,将 Response 事件分发到了 OKHttp 的全链路处理器中,进而实现了全链路上报设计的统一 。
2.3.1.3 遇到的问题
(1)超时时间处理
由于 CronetHttpURLConnection 提供的部分超时时间设置是空实现,而通过 Native Cronet 设置的超时时间也并不符合预期,通过 ConditionVariable 实现超时也未免过于冗余 。
CronetHttpURLConnection 内部维护了一个类似于安卓处理管理机制 Message + Looper 的 Task 处理器——MessageLooper,MessageLooper 中维护了一个阻塞队列,并提供了超时的控制策略,通过建立同包名类间接继承 package 访问权限的 MessageLooper,通过反射替换封闭的 MessageLooper 为 NRMessageLooper,进而可以获得超时时间的灵活控制权,在此基础上,我们增加了超时时间的动态下发,以便于风控配置 。
对 Cronet 库的定制如 图7 所示 。
大厂技术分享:网易新闻 QUIC 敏捷实践

文章插图
图7 网络库定制架构图
(2)请求占比优化
最初,客户端 QUIC 协议请求占比在统计上报上来的数据观测中并不理想,为了提升 QUIC 占比,我们在与 CDN 共同排查后,优化了双方的处理方案,客户端转用 CronetHttpURLConnection 处理,CDN 侧同时优化处理,并对网络节点也进行了相应调整,保证了两侧方案的统一性,并再次降低了平均响应时间与错误率 。
2.3.2 iOS
在 iOS 网络库接入方面,调用 Cronet 的 setMetricsEnabled 接口开启 Metric,通过 URLSession 回调获取 networkProtocolName 属性,可以获取当前网络请求的协议类型,以更有针对性地进行数据衡量 。
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)taskdidFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0))QUIC 项目上线3.1 切量控制
由于 QUIC 改善的拥塞控制与更低的建联时间,都传递给我们了一个信息:QUIC 对改善视频卡顿等场景有所增益,所以,我们最初的方案选取测试视频域名,而最终视频的卡顿率也有所优化,在弱网场景则更加明显 。
由于切量到 QUIC 测试,视频域名需要同步从 HTTP 切换到 HTTPS,这样会增加 QUIC 测试干扰项,为了更好地观察数据,我们设计了 QUIC 的两套切量策略,保持一部分原有域名的请求,并将又一部分原有域名也切换到 HTTPS,而 QUIC 测试将另一部分原有域名切换为 CDN 域名进行测试,切量控制如 图8 所示 。


推荐阅读