第一篇认识TCP通信延迟,试图总结了一下复杂的网络通信一些原理、算法基本思路。目的就是为了说明一下绝大部分web应用所依赖的底层TCP通信协议机制带来“延迟”的问题和一些常见的优化的手段。
以前在电信业务系统里面有一段较长从事实时计费OCS的经历,其中一个比较重要的核心技术方面就是网络通信。但是自从开始研究学习web领域的通信之后,发现私有标准协议下的socket通信的要求主要是稳定性和高性能,而且传输的数据量大多也控制在比较小的范围内容。另外长连接的预建立机制,也省去了请求即启动连接过程的开销,面临的场景与HTTP应用完全不同。
HTTP作为应用层的标准协议,这类应用所面临的情况与私有协议下socket通信的场景完全不同。它所面临的情况:
1.请求突发性(这个部分类似实时计费也有同样场景),但是请求的突发性是伴随着连接建立而运行的,那就意味着假如没有连接复用机制的话,HTTP每次请求都需要经历一次TCP连接建立的延迟开销。另外即使是持久连接情况下,也只是减少了这种连接开销的数量。
2.资源多样性,资源大小不缺定性。HTTP请求访问资源类型不断增多,文本、图片甚至视频等。其中资源请求的大小也不固定,尤其大型网页首页,比如淘宝,都需要使用很多优化手段,包括将资源限制在较小范围内。
3.客户端软件,面向客户的浏览器针对提供的这一套web标准,有自身访问请求、加载资源渲染的过程,也会影响到请求资源最终给用户呈现的体验,性能、交互等方面。
4.另外HTTP协议制定和我们私有标准协议方面还是会存在差异,因为客户端和服务器只会按照支持的标准来各自实现,所以在HTTP协议上面有一系列的控制标记,用于客户端和服务器之间建立连接、请求资源的协商机制的。
HTTP类应用中最常见的客户端入口就是浏览器。当然理论上支持HTTP标准协议访问的客户端程序都可以。浏览器基本上成为了用户通过HTTP协议访问web资源的最常见入口。
1.一次HTTP应用请求交互过程
我们来通过基于HTTP协议的web应用来看一下这个基本的通信过程。
1)通过打开浏览器,输入某个正确的URL,比如http://s.migu.cn/st/html/miguIndex.html
2)HTTP第一次请求通过URL输入确认发起,建立与服务器之间的连接(底层TCP建立连接,根据IP+端口号建立连接)。URL里面就包含了服务器端连接信息,可以直接是IP地址+端口号,也可以是定义好的域名。TCP连接建立之后,该请求HTTP报文主要向服务器请求访问
miguIndex.html这个资源文本文件。URL中的
域名“
s.migu.cn
”会根据DNS解析找出具体服务器IP地址相关信息。
3)服务器接收该HTTP请求报文,会按照URL里面定位的资源,组装应答响应HTTP报文,在应答的报文中传输
miguIndex.html文件内容(基于该TCP连接之上)。
4)浏览器接收到HTTP应答报文并解析报文内容,开始解析
miguIndex.html具体内容。
5)解析接收的
miguIndex.html内容是HTML格式的,会按照HTML语法来一行行解析和展示,整个过程对
miguIndex.html内嵌的各种独立资源,比如css、图片、js脚本等都会建立独立的连接或者复用持久连接进行HTTP资源访问的请求和传输。最终用户见到访问地址的首页,当然页面显示的元素也会根据整个布局设计在不同的时间按照一定的顺序出现。
理解几个概念:
1)资源
web应用中访问的内容都称为“资源”,资源的内容从HTTP协议早期定义的超文本文件HTML,不断扩充到图片、视频、Javascript等脚本应用以及各类网关后面领域系统的数据。
从这一点看基于标准的HTTP协议web类应用方式会发展为互联网化在线+开放领域的标准。
2)资源标识
web应用里面所有资源都会有一个名字,这个名字叫URI “统一资源标识符”,用于客户端在事务中标注需要什么资源。其中URL“统一资源定位符”是URI的一种常见的表示方式,用于描述某一个访问的资源在服务器特定的位置(资源是丰富多彩的,而且会越来越多)。比如:
a. http://s.migu.cn/st/html/miguIndex.html
,表明从指定具体精确的服务器位置上面获取一个HTML文本资源。
b. http://s.migu.cn/st/js/flexible.js
,
表明从指定具体精确的服务器位置上面获取一个js应用资源。
c. http://s.migu.cn/st/css/style.css
,
表明从指定具体精确的服务器位置上面获取一个css样式资源。
d. http://s.migu.cn/st/image/index1.png
,
表明从指定具体精确的服务器位置上面获取一个图片资源。
URI还有另外一种形式是URN(统一资源名),这种表达方式可以作为特定资源的唯一名称,与资源所处的位置无关。意味着可以将资源到处迁移,只需要通过名字来进行网络资源统一访问。不过这种理想的方式由于需要背后统一的解析框架来实现,目前没有普及,这里先不记录。
3)HTTP请求/响应机制
HTTP类应用客户端和服务端交互机制是请求/响应方式,我们很少见到在HTTP协议通信上能有服务器端主动推送资源的情况,当然这个特性正在被一些新的技术实现改变,这个后面再说。正常情况下,一个HTTP事务构成如下:
a. 一条从客户端发往服务器的请求命令
b. 一个从服务器应答的结果。
c. 通信是通过HTTP报文定义的格式化的数据块进行的。(HTTP协议定义,协议的理解对电信行业的从业人员应该很熟悉,因为电信行业应用各类协议非常多,各种网元协议,3GPP协议等)
d.
底层都基于TCP/IP协议,通过IP+端口建立连接。
4)客户端浏览器对页面的解析和展示
客户端浏览器根据URL请求相应的资源,最先到达的肯定是某个页面的文件构成客户端查询的视图,当然也可以是定位请求某个具体图片,但是一般情况下都会是按照请求首页方式来解析展示。然后将所有这个首页里面的所需要使用的图片等资源内嵌在里面,在解析首页时再去建立请求来获取资源。
浏览器对页面获取的资源数据的解析和布局展示,这个过程还是比较复杂的,当然学习也有一定规律。其中一个专业名词“渲染”,就是对访问页面的解析和展示的过程。因为资源多样,因此就会涉及资源下载、解析和渲染展示相互依赖关系,需要根据面向用户提供的访问体验偏好很好的平衡它们。
浏览器对页面渲染的第一步肯定是先下载HTML资源文件数据,然后开始构建DOM(文档对象模型),DOM就是HTML中各个元素按照层次结构,构建结构对象。类似这样如下。
在解析下载的HTML中可能会涉及对页面定义的CSS资源,同样的建立连接获取相应内容,然后开始构建CSSOM(CSS对象模型),这个主要定义页面的一些布局,样式表,元素一些大小等信息。
当然还可能有各种图片资源等。需要引起重视的就是资源中的类似javascript脚本应用程序,因为
javascript程序里面一些同步操作阻塞DOM或者CSSOM的构建。而且页面进入渲染之前的时间,就和这三者之间依赖关系有关。所以一般写HTML页面都要求“样式在上面,脚本在下面”,样式最先下载了,不影响后面渲染或者脚本的运行。
DOM这样的文档结构对象构建完成之后,就开始构建渲染树,构建渲染树是个比较复杂的过程,
不详细说了,整个过程还是蛮复杂的,专业的前端工程师能给出比较体系的分析,另外这也是浏览器解析原理,不在本篇范围之内。总之渲染树构建完毕之后就开始布局的计算和最终绘制页面内容展示,这个过程可能会来回交互几次,完成最终的页面解析展示。
2.HTTP应用访问实例
借着这个简单的访问场景,我们来分析看一个实际访问首页的过程,熟悉了解下HTTP类应用的交互机制。
使用web应用性能测试的工具,输入自己搭建的web容器URL为“http://114.115.202.76:3389/
”,来看一个最基本的tomcat测试首页的访问。
首先首页的访问没有指定HTML文件名,那是因为Tomcat容器测试首页默认指定好了资源文件,只需要从开放指定端口上的请求,默认访问映射好的首页HTML资源。
1)测试数据汇总
整个首页加载一共向访问的服务器地址发起了5个请求,第一次访问的时间和第二次访问时间相差比较大,主要是因为第二次访问有部分资源信息本地化缓存,就不需要再耗费时间加载了。
a. Doucument Complete统计,表示加载整个首页资源耗费的时间,不包括可能有js文件中需要重新加载内容的时间,只是首页里面所有资源加载耗时。另外就是请求的数量和总下载资源的大小统计。
b. Fully Loaded则是整个页面资源加载和js中包括触发的活动时间和请求数的统计,包括下载总资源大小。
2)资源请求和加载过程
来看一个首页以及其元素请求的过程。图表中,不同的颜色表示了耗费的时长,以及在首页加载过程中的顺序。
从整个首页访问来看,Tomcat默认首页主要加载的资源包括index.html首页、 tomcat.gif
、 asf-logo-wide.gif
、 tomcat-power.gif
和 favicon.ico
。
a. 整个资源请求访问,浏览器一共发起了5次请求,建立了三个连接。
三个连接因为直接给出的IP地址信息,所以整个连接过程省去了DNS解析的时间。
b. 连接建立允许并发建立,
这个并发的数量在浏览器有限制,主要还是考虑服务器得压力情况。另外并发得连接上面
加载资源数据也需要视服务器得处理机制和能力来看。
c. 从资源请求来看,允许请求在同一个连接上面加载传输,也就是支持建立得连接复用,这样减少不同资源请求建立多连接得开销。
b. 整个资源加载顺序上面,首先加载默认的首页
index.html文件,然后开始解析从连接上响应的
index.html文件的内容,根据解析页面过程中按照内嵌资源的位置等顺序,建立新连接或者复用持久连接请求和响应下载资源。
c. 连接建立上面,看得出有连接上面有先后顺序的发起两个资源请求和下载。同时连接支持并发的去建立,在叠加的时间里面请求和响应资源,但是在相同连接上面必须按照顺序来执行。
3)连接视图
从连接视图来看,可以看到连接建立顺序,每个资源加载的顺序。
a. 两个连接并发建立,每个连接上面资源请求和响应都按照顺序来进行的,同一个连接上面请求是串型加载。
b. 从连接上面不同颜色资源下载进度来看,可以看到哪些资源在复用同一个连接,减少底层TCP建立连接的延迟消耗。
4)请求明细
请求明细中可以查看到每个资源请求过程中得一些参数。
a. 请求资源得URL,用于定位服务器资源位置
b. 请求资源类型,表示请求资源归属得类型。
c. 请求开始得时间,以及请求资源期间如果需要建立连接,连接初始化所需要消耗得时间,之前TCP建立得延迟。
d. 每个请求资源得大小,这个也是请求传输资源得重要影响因素。
3.HTTP类应用性能考虑
理解HTTP类应用性能的影响因素,对整个web应用性能优化有帮助,首先我们来看看HTTP应用一次访问性能开销的内容。
1)TCP通信延迟,第一篇已经说明过,整个HTTP应用建立在TCP连接基础上,而且具有突发访问等特性,所以TCP连接本身建立过程中的延迟是性能影响因素之一。尤其对于HTTP类应用,访问一个大首页至少几十个请求的建立,每个TCP连接延迟几百毫秒,叠加一起对整个首页的加载影响就会比较大。
2)整个HTTP应用访问通过URI中的URL来访问,如果通过域名访问,首次访问需要加上DNS域名解析部分的开销,最终解析域名,根据IP地址加端口方式来建立后续连接。
3)加上所有的资源下载都需要通过多个连接上发送请求报文以及资源响应传输数据的时间,构成数据通信过程中的时延,这个时延会取决于机器配置、网络和服务器的并发负载情况,请求和应答报文大小,客户端和服务器端的距离等影响。
4)浏览器对开发的HTML等文档解析,应用开发这些访问资源布局和设计也会影响整个应用的性能,比如超文本中支持的脚本应用这些资源,内部实现可能会影响到页面的解析展示。
来看看HTTP1.1协议在这方面的机制:
1)支持持久连接
HTTP1.1版本默认支持持久连接的,从HTTP报文头部字段Connection默认设置为keep-alive。但是持久连接是有数量限制,同时持久连接关闭也允许客户端和服务端通过
Connection设置close来协商交互过程,同时这也取决于服务器对关闭持久连接的策略,有的可能在连接空闲指定时间后进行关闭。
这种特性会引发另一个问题,因为TCP连接是双向通道,在关闭期间如果数据存在传输,客户端就会出错,客户端重新发起请求操作存在的重复提交的风险,所以正常要求在更改服务器端的请求中注意幂等的特性。
2)
支持并行连接
支持多个连接同时打开,并行的来执行多个请求事务。在一个页面中多个图片请求下载中,并行连接会让用户感觉比较快,体验好一些。但是由于考虑到服务器的压力,一般并行连接的数量也会进行限制,不同浏览器都有对应的默认限制值。
web应用开发需要关注点:
1)持久连接使用也需要关注何时关闭
TCP连接建立开销延迟不低,因此能够复用连接一定要尽量复用。HTTP主流的1.1版本支持持久连接机制,并且是默认支持。但是,由于浏览器这种没有预期访问特性,如果长连接保持过多,大量用户访问也会对服务器产生很大的压力。因此,在连接建立和复用上面也会需要平衡。
如果自己实现HTTP服务器,那需要关注持久的连接在什么样的策略下关闭,大多数HTTP服务器都会考虑这些策略,这个可以在后面研究分享下。这个关闭策略也会跟服务器承受并发负载相关。
2)缓存
web应用不同于C/S结构的应用,C/S结构的应用是基本访问框架在客户端入口一次安装,后续请求都是更新数据。web应用相当于每次访问都要来一次安装过程。所以,在这类应用的机制上面,基本上是能缓存的就会缓存。
第二次访问的时长,明显要远低于第一次,那是因为客户端浏览器缓存机制,将访问地址的相关资源通过第一次访问进行缓存,提升访问的性能。当然客户端浏览器缓存容量是有限的,这种缓存有一定的机制来保证缓存时长、缓存满后替换策略。
另外一种就是
通过网络中对访问客户群体就近部署缓存服务,比如CDN将访问静态类的数据推送至客户端就近的机房接入点,让客户端访问服务器端资源减少网络传输的中间交换节点,从而降低传输资源数据延迟开销。可以从附录中对淘宝网首页的测试过程中看出对CDN的访问连接信息。
3)压缩传输,减少通信连接上传输数据量
既然这种应用的特性导致了每次请求访问的开销不可避免,那每次资源如果能尽量减少传输数据量,也会减少这部分开销。当然肯定会增加客户端图片等压缩资源展示的开销,这个与客户端界面体验有关。
比如淘宝网如下的图片格式,使用了谷歌的
WebP格式
图片格式。图片支持压缩能力,会进一步减少访问资源的大小,用来节省服务器带宽资源和数据空间。
4)资源分散存放
单服务器上面承载请求压力的负载毕竟有限,从分而治之的思路角度来看,将web请求访问资源分散机器存放也是一种性能优化策略。甚至在这个存放的方式上面还可以利用缓存服务提升性能。
5)多从客户交互体验角度考虑
既然每次访问资源请求下载肯定是少不了的,除了通过缓存这些来减少传输以外,在页面的布局上面也要多从用户角度来考虑。
页面请求加载过程中哪些东西需要尽快与用户见面,交互的机会点在哪里。浏览器渲染的流水线中,实现机制是怎样的,怎么能影响到开发出来的首页的布局等。
附录
(会受地域、客户端网络实际情况测试结果会不同)-相比咪咕营销平台首页加载时间和淘宝网首页加载性能还是优化的非常好的,基本上CDN、分散资源存储,重定向连接、压缩资源都使用了。:
1.淘宝网访问加载首页情况:
2.请求资源过程跟踪
3.连接建立视图