现在轮到咱们实际上可以控制的东西了。浏览器
网络处理的性能与延迟时间的添加是不成比例的。缓存
这是由于大多数网络协议的内在操做是双向信息交换。安全
本章的其他部分则側重于理解为何会产生这些信息交换以及怎样下降甚至消除它们交换的频率。微信
图3:网络协议cookie
传输控制协议(TCP)是一种面向链接、基于ip的传输协议。TCP影响下的无差错双工通讯信道对其它协议如HTTP或TLS来讲都不可缺乏。网络
TCP展现了不少咱们需要尽可能避免的双向通信。这当中一些可以经过採用扩展协议如TCP Fast Open协议来替代;还有一些则可以经过调整系统參数来达到最小化。比方初始化拥塞窗体。在本节中,咱们将探讨这两种方法同一时候也提供一些TCP内部组件的背景。架构
初始化一个TCP链接约定需要3次信息交换。也就是咱们所说的3次握手。TCP Fast Open(TFO)是TCP的一个扩展,它消除了一般握手过程当中的往返延迟。异步
TCP在client和服务端的三次握手协商操做參数使得两方作健壮的双向通讯称为可能。最開始的SYN信息(同步信息)表明client的链接请求。假设服务端接受这个请求,那么它将返回一个SYN-ACK消息(同步和接受消息);最后。client发送一个ACK消息来应答server。分布式
这时,一个逻辑链接就已经创建完毕,client就可以发送数据了。性能
这当中你假设注意到。3次握手过程当中至少引入了一个RTT的延迟那就很是好了。
图4:TCP3次握手
从传统角度来看。除了对链接进行回收利用外没有其它方法来避免TCP3次握手形成的延迟。
然而,这样的想法发生随着Tcp Fast Open IETF规范的引入发生了变化。
TFO赞成client在逻辑链接创建以前就開始发送数据。这实际上否认了3次握手中的往返延迟。
这样的优化的累积效应是让人印象深入。
依据谷歌的调查。TFO可以下降页面40%的载入时间。尽管这个规范仅仅是草案,但是TFO已经被主流浏览器(Chrome22以上)和平台(Linux3.6以上)所支持,并且其它供应商也保证将在不久之后会全然支持它。
TCP Fast Open是对3次握手协议的一个修正,它赞成在同步消息(SYN Message)内有少许的数据负载(如HTTP请求)。这个有效负责会传递给应用server,不然链接握手完毕。
早些时候扩展方案像TFO终于因安全问题而失败。
而TFO经过使用安全令牌或者cookie来解决问题。也就是说在传统的TCP链接握手过程当中给client分安全令牌(tooken),并且指望将安全令牌包括在TFO优化请求的SYN消息中。
对于TFO的使用。这里有一些小的警告。当中最值得注意的是,在初始化的SYN消息中请求的数据缺少幂等性保证。尽管TCP保证反复数据包(反复经常发生)会被接受者忽略,但是这个保证并不适用于链接的握手过程。眼下在规范草案中正在标准化这个解决方式,但是于此同一时候TFO仍然可以被安全的应用于幂等性处理。
初始拥塞窗体是TCP的一个可配置项并且有巨大的潜在能力来加速小的网络事务。
近期的IETF规范促进一般的初始拥塞窗体的设置增加到3个报文段(如数据包)到10个报文段。这个建议是基于谷歌进行的普遍研究,这个研究证实了这个參数的设置对性能有平均10%的提高。但假设不介绍TCP的拥塞窗体(cwnd)的话。这样的设置的目的和潜在影响就不会被真正领会。
当在一个不可靠的网络上进行操做时,TCP来保证client和服务端的可靠性。
这至关于一个承诺,所有发送出去的数据都会被接收到,或者至少看起来是这样。
当中,包丢失是知足可靠性要求的最大障碍,这需要侦測、纠错以及预防。
TCP採用一个确定应答机制来检測丢包状况,即每个发送出去的包都应该被它预约的接收方应答,假设没有应答就意味着这个包在传输过程当中丢失。
在等待确认的过程当中,数据传输包保存在一个特殊的缓冲区中,也就是所说的拥塞窗体。当这个缓冲区被塞满时。一个被称做cwnd耗尽的事件发生,所有传输中止,直到接收方应答后腾出有效空间来发送不少其它的数据包。这些事件在TCP性能中相当重要。
除了网络带宽的限制,TCP吞吐量根本上受cwnd耗尽事件发生频率的限制,而这可能与拥塞窗体的大小有关。当TCP性能达到峰值时需要一个拥塞冲口来调节当前的网络状态:拥塞窗体过大将添加网络阻塞的风险--过分拥堵的网络情况会添加大量包丢失。太小则珍贵的网络带宽将不能充分被利用。从逻辑上讲,对网络状况了解的越多,肯能越能选择一个最佳的拥塞窗体大小。
实际状况则是。关键网络属性比方容量和延迟,是很是难衡量的而且不断在变化。
而且,假设一个基于互联网的TCP链接需要穿过不少网络的这又会是一件更加复杂的事情。
由于缺少手段来准确肯定网络容量大小,相反TCP经过网络拥堵状况来判断拥塞窗体大小。
当TCP发现有包丢失时它就会扩大拥塞窗体的大小,提示下行某处有一个网络没法处理当前的传输速率。经过採用这样的拥塞避免机制,TCP终于最小化cwnd耗尽事件在某种程度上它消耗完为所有链接所分配的容量。那么现在,终于,咱们也达到了目的,解释清楚了初始拥塞窗体參数的重要性。
网络拥堵状况仅仅能经过丢包測试来检測。一个新的或者空暇的链接由于没有足够丢包数据来证实建立拥塞窗体的最佳大小;TCP採用了一个比較明智的作法就是以一个可能最小状况致使网络拥堵的大小一開始做为拥塞窗体大小。这最初意味着需要设置1个分片(大约1480字节),而且有些时候这样的作法是推荐的。
而稍后的实验会演示一个高达4的设置也是有效的。在实践中你也一般发现初始拥塞窗体设置为3报文段(大约4kb)。
初始拥塞窗体不利于小的网络事务处理。
这样的效果很是easy说明。在表中的3个报文段设置下,在发送3个数据包或者4k的数据后cwnd耗尽时间就会发生。若是数据包是连续发送的。响应的响应不会在不论什么所赞成的往返时间(RTT)以前到达。假如RTT是100ms的话,那么有效传输速率仅仅有可怜的400字节/秒。虽然TCP会调节自身的拥塞窗体来充分利用有效容量,但是它在一開始将会很是慢。
其实。这样的方式被称为慢启动。
为了下降慢启动对较小的下载的性能影响,它需要又一次评估初始拥塞窗体的风险回报。
谷歌正是这样作的,而且发现将初始拥塞窗体设置在10个报文段(约14kb)会在最小网络拥堵状况下达到最大吞吐量。
现实世界中也证实了这样设置总共可以下降页面10%的载入时间;链接的往返延迟将获得更大的改善。
改动初始拥塞窗体的默认值也并不是那么简单的。
在大多数server操做系统下,一个系统级的配置仅仅有有特权的用户才可设置。这个參数也很是少甚至不能被没有权限的应用在client配置。需要注意的是一个更大的初始拥塞窗体在server端可以加速下载,而在client则可以加速上传。假设没法在client改变这个设置就意味着应该特别努力去下降请求负载的大小。
本节将讨论在超文本传输协议(HTTP)性能方面来下降高的往返延迟的技术。
KeepAlive是一个HTTP约定来赞成同步连续的HTTP请求来使用同一个TCP链接。
至少一个单组往返请求所需要的TCP的3次握手可以避免,每次请求可以节省几十或者几百毫秒。更深层次的,keepalive另外一个额外的但是未被说起的优势就是它在各个请求之间保留了当前TCP的拥塞窗体大小。这将致使更少的cwnd耗尽事件发生。
图5:HTTP pipelining
实际上,管道使网络延迟分布于网络往返的各个HTTP事务中。好比,5个管线式的HTTP请求经过一个100毫秒的RTT链接时将产生一个平均20毫秒的往返延迟。在相同条件下,10个管线式请求时这个平均延迟将下降到10毫秒。
但是,HTTP pipeling有明显的缺点阻止了它被普遍使用,即历史上參差不齐的HTTP代理支持和拒绝服务攻击的影响。
传输层安全性(Transport Layer Security,TLS)是一个面向会话的网络协议赞成在公共网络安全地交换敏感信息。
尽管TLS在安全通讯方面卓有成效,但是在高延迟网络下它的性能会降低。
TLS採用一个复杂的握手协议包含两次交换client-服务端信息。一个TLS安全的HTTP传输明显比較慢也正是这个缘由。一般,发现一个TLS慢其实是在抱怨它的握手协议中多重往返所产生的延迟。
图6:DNS查询
一般。主平台提供了缓存实现来避免频繁的DNS查询。DNS缓存的语义很easy:每个DNS响应包括一个存活时间(time-to-live,TTL)属性来声明结果会被缓存多长时间。TTL的范围一般在几秒钟到几天之间,但一般为几分钟。很低的TTL值。一般在一分钟下面。被用在影响负载分配或者下降server替换或ISP故障转移的时间。
高可用系统一般依赖于他们IP机房的冗余基础设施主机。TTL值较小的DNS条目可以下降客户指向失败主机的时间,但是同一时候会致使大量额外的DNS查询。
因此说,TTL的值应该是下降停机时间和client性能最大化的一个折中。
一般减小client性能是没有意义的,但当server故障时是个例外。有一个简单的方法来解决问题,也就是说不是严格的遵照TTL。而是只当更高层协议如TCP或HTTP检測到不可恢复错误时才刷新DNS缓存。这样的技术在大多数场景下模拟TTL保持DNS缓存一致的行为。然而这差点儿消除了不论什么基于DNS高可用性解决方式中的性能损失。
但是需要注意的是这个技术方案和其它基于DNS的分布式负载方案不兼容。
异步刷新是一个DNS缓存方法,它遵照已经设置TTL规则但是在很是大程度上消除了频繁查询DNS的延迟。在这项技术中,需要一个异步DNSclient库如c-ares来实现。
这种方法很是easy,一个过时的请求仍然返回的是老的结果,但是后台有一个非堵塞的DNS查询来定时刷新DNS缓存。这样的方案假设採用堵塞式(如同步)回调来查询每条老的DNS数据,那么这个方法差点儿不受DNS查询延迟的影响,但是仍然和很是多基于DNS的故障转移方案以及分布式负载方案兼容。
要下降移动网络高延迟的影响就需要经过下降使移动网络延迟急剧添加的网络往返次数来实现。而採用软件优化专一于最大限度地下降或消除往返协议的消息是克服这项艰巨的性能问题的关键。
(移动网路性能篇。全文完。)
1. 本文由程序猿学架构翻译
2. 本文译自The Performance of Open Source Software | Secrets of Mobile Network Performance
3. 转载请务必注明本文出自:程序猿学架构(微信号:archleaner )
4. 不少其它文章请扫码: