网络优化解决的核心问题有三个,第一是安全问题,我们在系列《一》DNS优化进行了详细的讲解。第二是速度问题,我们在系列《二》连接优化也做了详细的介绍。第三是弱网问题,它是网络优化中最为复杂且需要反复验证和分析的问题,我们的系列《三》弱网优化就是要深入探讨这个问题。
弱网优化需要解决的核心问题有两点
【1】移动网络环境如此复杂,我们如何确定当下就是弱网环境。
【2】确定为弱网环境下,我们如何提升弱网下的成功率,降低弱网下的时延,进而提升用户的网络体验。
百度App承载着亿级流量,弱网比例0.95%,可谓不小,这个比例是如何得来的呢?还是要从什么是判断弱网指标说起。
首先我们来探讨下都有哪些指标会影响到网络的质量,包括httprtt,tcprtt,throughput,signal strength,bandwidth-delay product。
1.httprtt httprtt(http Round-Trip Time)又名TTFB(Time to first byte),指从客户端请求的第一个字节开始发送到接收到http header的第一个字节的时间差。httprtt的时间如果过长,一方面是客户端本身接入网络质量的问题,另一方面是服务的延时比较大。
2.tcprtt tcprtt(tcp Round-Trip Time)指客户端tcp信道第一个字节发送到接收第一个字节的时间差。因为HTTP协议底层是基于TCP的,所以在复用同一条tcp连接的前提下,httprtt的时间是包含tcprtt的时间的。大部分情况下httprtt已经可以说明问题的原因。
3.throughput throughput,中文名字吞吐量,它是用来衡量单位时间内成功传送数据的数量,是可以比较客观的衡量网络质量的指标。吞吐量 =(获bits结束大小 - 获bits开始大小)/(获bits结束时间 - 获bits开始时间),这里有个细节需要注意,posix socket的read函数返回值是bytes,所以要乘以8得到bits。通常在httprtt比较小的情况下,网络依然很慢,这个时候就可以使用吞吐量来确定网络的质量。
4.signal strength signal strength,这里指的是无线信号强度,在Android上可以通过PhoneStateListener的onSignalStrengthsChanged方法获取到信号强弱,但要注意只能在Android M以上的版本才生效。iOS上暂时没有靠谱的实现。
5.bandwidth-delay product bandwidth-delay product,中文名带宽时延乘积,指的是一个数据链路的能力(throughput)与来回通信延迟(rtt)的乘积。带宽时延乘积的结果是比特不是位,这个比特值反应出当前网络管道的最大容量。TCP中有一个窗口大小的概念,会限制发送和接收数据的大小,所以TCP窗口大小的调节是直接受带宽时延乘积的影响,根据带宽时延乘积的值去设置套接字的setsockopt方法,设置的option是SO_RCVBUF(接收缓冲区大小)和SO_SNDBUF(发送缓冲区大小)。
通过上面的内容,我们对影响网络质量的指标有了一定了解,对于不同的产品,影响网络质量的指标可以理解成一样的,但对于每个指标的阈值肯定是不一样的,因为这包含着业务场景,比如抖音是视频类网络传输,微信是长连接数据传输,百度是文本图片类数据传输。还包括服务端配备,不同产品线的服务集群能力肯定不一样,比如返回客户端的服务端耗时肯定不一样。所以针对不同的产品弱网指标是基本一致的,但是指标的取值肯定是不一样的。
建立弱网标准是一个循序渐进的过程,在一穷二白的时候我们应该如何建立这个标准呢?答案分为三个阶段。 如下为建立弱网标准的步骤:
1.第一阶段,线下进行测试。获取一些符合我们预期的阈值,这个时候我们需要借助一些网络测试工具,比如苹果的Network Link Conditioner,Facebook的ATC(Augmented Traffic Control),来获取到线下不同网络情况的阈值,一般我们会测试App冷启动的场景,网络切换的场景,DNS故障场景,弱网场景(一般都是配置上下行的带宽,丢包率,延迟,DNS延迟参数,或者更为简单的是使用工具默认的一些弱网配置)。
2.第二阶段,线上进行验证。通过线下充分测试获取到的阈值,在线上可以获取到弱网的比例,在这里百度App是针对特定场景的,比如Feed刷新,搜索落地页打开等,就算是在移动时代被大家公认的网络体验好的微信,也只是在信令传输(收发消息)上做到极致优化,所以针对场景搜集弱网数据很重要。
3.第三阶段,线上的反复试验。想做到理想的弱网效果,少不了线上反复的阈值调整,通过调整阈值比较针对场景的网络请求的成功率、耗时、连接复用率等指标,使我们获得趋向于针对场景的合理阈值。
聊了这么多,那么弱网的探测如何实现呢?
网络探测是弱网检测的基础,是否能即时,正确的检测出网络质量,是我们首先要解决的问题。我们把网络探测划分为两部分,主动网络探测和被动网络采集。
所谓主动探测,就是在触发了某些条件后,主动的进行网络探测,并按照一定的条件检查出是否是弱网状态。百度App自研了主动探测组件,如下图所示。
探测策略层通过多种策略的组合,使主动探测的即时性和准确性得以大大提高,我们结合上面的策略层图来解释下检测维度的意义。
我们分别在网络请求成功和失败的时候触发了弱网检测的逻辑。主要分为如下三种逻辑。
1)成功时,如何判断进入弱网状态?检查weakhttprtt的阈值,这个值取决于业务的设置(一般这个值会针对特殊场景的请求取95分位或者更大分位的值),大于这个值就会进入弱网检测,为了防止频繁触发探测加了时间间隔维度,目前定义的是10分钟。从线下模拟测试来看,只要大于这个阈值,检测结果必然是弱网状态。
2)成功时,如何判断退出弱网状态?检查goodhttprtt的阈值,这个值取决于业务的设置(一般这个值会取整体网络的95分位或者更大分位的值),小于这个值证明要切换回正常网络状态,为了防止频繁触发探测加了时间间隔维度,目前定义的是30秒。从线下模拟测试来看,只要小于这个阈值,检测结果必然是正常状态。如果大于或者等于这个阈值,也不能证明一定不是正常网络,所以也需要发起网络探测,但是由于这是在成功回调里,频次会很高,所以我们加上时间间隔的限制30秒,还加入了次数的限制,连续成功次数%次数阈值(4次)等于0。但这看起来还是频次有点高,所以我们引入了阶梯递增机制,随着次数的增长,成60秒几何倍数增长。
3)失败时,如何判断进入弱网状态?首先会判断连续失败次数,连续失败次数/次数阈值(2次)等于1并且连续失败次数%次数阈值(2次)等于0,相比成功,失败的次数检查较为苛刻,主要还是考虑多次触发网络检测损耗性能。
进入弱网状态后,就会触发基础能力层的ping和dns query的探测。
探测基础能力层,主要提供弱网检测的手段,一是dns query,一是ping,百度App使用C++实现了这两个能力。为什么要选用这两种手段呢?我们在系列二中介绍过,一个网络请求,分为DNS-》TLS-》TCP-》数据传输 四个阶段。想判定网络连通性主要在DNS和TCP阶段,所以dns query和ping就是用来检测这两个阶段的连通性手段。dns query向百度核心域名mbd.baidu.com发起dns查询,查询的DNS服务器为系统配置的DNS服务器(iOS通过res_ninit函数构建一个__res_state的结构体,Android通过systemproperty获取net.dns1和net.dns2的值,便可获取系统配置的DNS服务器),DNS查询的超时时间为3s。ping的目标地址为百度核心域名mbd.baidu.com,ping的次数为两次,每次超时时间是默认的1s。
判断出弱网状态后,会将结果提供给接口层。
接口层主要提供主动探测出来的网络状态,目前包括GOOD,BAD,UNKNOWN,OFFLINE。
2.被动网络采集 所谓被动采集,就是每一次网络请求的所有细节都进行记录,并按照一定的条件将原始信息进行上报,上层再根据条件判断是否是弱网状态。百度App基于cronet的NQE(Network Quality Estimator)进行了二次订制开发。
首先我们讲解下需要采集的数据,包括tcprtt、httprtt、throughput三个维度,如下图所示。
1)tcprtt,基于posix和windows的socket编程接口来获取tcprtt。获取时机在连接完成,读完成和写完成。
2)httprtt,基于HTTP协议栈实现,通过计算接收response数据开始和开始发送的时间差,来获取httprtt。获取时机在读首包完成时。
3)throughput,通过上面的计算公式需要获取bytes和时间,基于posix和windows的socket编程接口来获取bytes。获取时机在读完成时记录接收的bytes,在写完成时记录发送的bytes。时间的获取在吞吐量管理模块里完成,下面会讲到。获取时机在请求完成和请求销毁时。
如下为被动网络采集的整体架构图。
1.1能力层 能力层内容上面我们已经讲过,主要采集tcprtt、httprtt、throughput三个维度的数据。
1.2策略层 被动采集策略层通过多种策略的组合,降低各种采集数据的上报时机,降低性能的影响。
1)套接字管理模块,首先负责获取tcprtt的值,如何获取tcprtt呢?通过getsockopt函数获取tcp_info结构体里的tcpi_rtt值。其次由于tcprtt的上报频次比较频繁,所以做了1秒的时间间隔上报限制。
2)吞吐量管理模块,负责吞吐量的计算,上面介绍了计算公式,从网络活动监控器模块获取bytes,但吞吐量的计算单位是bits(位),所以将bytes乘以8。只有GET请求会被列入统计计算,并且至少要累计5个请求后才能开始统计计算。排除精准度的干扰,比如localhost,私有子网上的主机,特定用途子网主机,可参考RFC1918。
3)网络质量管理模块,从套接字管理模块获取tcprtt,从吞吐量管理模块获取吞吐量,并且在HTTP协议栈读首包完成时获取httprtt。获取到这三个值后,需要经过一些策略限制上报的频次,10秒间隔的限制;网络类型不能是UNKNOWN(1.3的第三部分会详细讲解);网络不能频繁切换;rtt和吞吐量总大小各300个。
1.3接口层 接口层主要提供被动采集出来的网络状态,目前包括GOOD,BAD,UNKNOWN,OFFLINE。
1)GOOD:3G和广义的4G,任一条件满足标记为GOOD状态。通过阈值标记3G和广义的4G,httprtt大于等于273ms,tcprtt大于等于204ms,即标记为3G状态。小于这两个值被标记为广义的4G,所谓广义的4G包含4G、WiFi、以及质量较好的各种接入网络。
2)BAD:慢2G,2G和httprtt大于1.31秒,任一条件满足标记为BAD状态。通过阈值标记慢2G和2G,httprtt大于等于2.01秒,tcprtt大于等于1.87秒,标记为慢2G。httprtt大于等于1.42秒,tcprtt大于等于1.28秒,标记为2G。httprtt大于1.31秒,为百度App的Feed刷新业务阈值。
注:上面涉及的时间值为nqe内部的机制,具有普适性。
3)UNKNOWN:非法的httprtt,tcprtt,吞吐量,任一条件满足标记为UNKNOWN状态。何为非法?值为-1为非法,那什么条件被标记为-1呢?首先初始化时会被标记为-1,其次在从来没有获取到过httprtt,tcprtt,throughput的值时,会使用本地默认的值做为判断标准,这是一种容错处理。
4)OFFLINE:依赖平台能力进行判断,Android平台依赖ConnectivityManager获取NetworkInfo,通过NetworkInfo的isConnected获取是否连接,如果未连接则判断为OFFLINE状态,如果NetworkInfo为空则判断为OFFLINE状态。
下图为百度App在弱网下的手段:
QUIC(Quick UDP Internet Connections)是新一代的互联网传输协议,最早源于Google,它的详尽内容可参考资料【3】,本章我们不做QUIC的科普介绍。
百度App的普通网络请求在弱网状态下会切换到QUIC,本章重点讲解下百度App针对弱网下开启QUIC后遇到的问题,一是开启QUIC一旦遇到问题是否可以回滚?二是在弱网下如何能让流量尽可能的走QUIC?针对这两个问题,我们的解决方案是QUIC升降级原理和QUIC预连接。
如上图QUIC部分所示,QUIC的升降级依赖于HTTP Alternative Services,HTTP Alternative Services是与HTTP有关的一个协议,它不是为QUIC专门设计的,在HTTP协议上主要负责新服务的替换,对于HTTP1.1协议,它是通过HTTP响应头传输回来的,所以只能在第二次请求时生效,如下面格式。
Alt-Svc: quic="alt.example.com:443", quic=":443"; ma=2592000
如上信息表明切换到quic协议,指定了域名服务和端口,并且指定了生效时间,以秒为单位。
Alt-Svc: clear
如上信息表明将alter配置清空
在网络库内部有一个alter连接和原连接的竞争机制,如果alter信息已经存在,优先发送alter连接,而原连接会延迟发送,延迟时间默认300ms,谁先成功就使用哪个连接,如果alter连接在QUIC握手时失败,会记录这个alter信息的失败次数,并根据失败的次数,计算出一个过期时间,这个过期时间会随失败次数指数增加,最长为2天。当过期时间到期后,会清除这个alter信息,当这个alter连接在QUIC握手成功后,会清除这个alter信息。
所谓QUIC的预连接,就是在进入弱网状态前提前建立QUIC连接。大家都知道QUIC引以为傲的0RTT,但第一次建立连接的时候是需要1RTT的,客户端首先会向服务器发送一个client hello消息,服务器会回复一个server reject消息,这个消息中包括了server config,有了server config后客户端就可以直接计算出密钥,完成0RTT,详尽内容可参考资料【4】。
通过上面的原理,客户端拉取server config的成功概率会直接影响QUIC在弱网下的流量,所以我们在App启动的过程中会做一次QUIC预连接,将server config拉取下来,这样等进入弱网后alter连接会大概率的竞争过原连接,进而走QUIC协议。
复合连接的具体原理可以查看《百度App网络深度优化系列《二》连接优化》里的具体介绍,百度App目前在弱网下只是针对图片网络请求开启了复合连接,因为图片请求不管是HTTPDNS结果还是localDNS的结果都是多个IP,这是满足复合连接的前提。在弱网下多IP的尝试会比单IP的结果好些,另外弱网的比例相对较小,复合连接对于服务器的负载也会小些。
下图为百度App网络整体架构:
百度App网络整体架构,以网络门面为中间层,隔离上层的最佳实践和底层的基础网络库。
客户端网络库的一部分工作量是在如何让最佳实践做的更好,在音视频上,不管是iOS的AVPlayer,还是双端的ijkPlayer,都是使用HTTPDNS组件接管DNS模块,没有全部接管网络模块。ReactNative的网络模块RCTNetworking,图片库Android的Fresco和iOS的SDWebImage,WebView组件Android的Chromium和iOS的WKWebView,以及百度App的自有业务,都是通过网络门面的接口层直接接管。而对于第三方业务考虑到与宿主耦合的关系,直接使用Android的HttpURLConnection和iOS的URLSession系统标准的接口。
网络门面主要包括,拦截器模块(提供给业务订制网络门面的机制)、并发队列模块(提供高中低以及非常高的网络请求优先级)、网络探测组件(弱网主动探测能力)、网络诊断模块(包括https,ping,dns的校验)、HTTPDNS组件(《百度App网络深度优化系列《一》DNS优化》里详细讲解)、网络监控模块(客户端的打点机制,服务端的例行和突发监控)、HttpURLConnection封装层、URLSession封装层。
基础网络库包含两部分,一部分是基于cronet二次订制的统一网络库,一部分是WebSocket基础库(Android的JavaWebSocket,iOS的SocketRocket)。统一网络库内部包含连接优化的内容(在《百度App网络深度优化系列《二》连接优化》里详细讲解),弱网优化的内容(上面提到的被动采集)。通过AOP的方式将底层协议栈注入进HttpURLConnection(利用URLStreamHandlerFactory)和URLSession(利用URLSessionConfiguration的protocolClasses属性),两者都是系统提供的URL Loading机制。
弱网优化的收益我们主要从上面讲到的进入弱网状态后的手段来看,包括开启QUIC,QUIC预连接,开启复合连接。
系列一到系列三的内容到今天全部完成,希望能对大家的工作和学习有所帮助,感谢大家的持续关注和鼓励。生命不息,优化不止,做技术我们是认真的。
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。