四、TCP/IP协议
拿到域名对应的IP地址之后,浏览器会以一个随机端口(1024<端口<65535)向服务器的WEB程序发起TCP的连接请求。这个连接请求到达服务器端后(这中间通过各种路由设,代理,局域网内除外),进入到网卡,然后是进入到内核的TCP/IP协议栈(用于识别该连接请求,解封包),最终到达WEB程序,最终建立了TCP/IP的连接。可以保证传输的报文永不丢失,受损或者乱序
(一)IP数据包
TCP的数据,是通过名为IP分组的小数据块来发送的。以流的形式将报文数据的内容,通过一条打开的TCP连接按序传输。TCP收到数据流之后,将数据流砍成小TCP数据段,并将其封装在IP分组中,通过网络进行传输。
每个IP分组包括:IP分组首部,TCP段首部,TCP数据块
IP分组首部包含了源和目的IP地址、首部长度、数据报总长、首部较验和等标记。
TCP段的首部包含了TCP端口号、TCP控制标记、和用于数据排序和数据完整性检查的一些标记。
(二)TCP连接
任意时刻计算机都可以有几条TCP连接处于打开状态,是通过端口号来保持所有的这些连接持续不断地运行的。
通过四个值来识别和唯一地定义一条连接:<源IP,源端口号,目的IP,目的端口号>。两条不同连接不能拥有4个完全相同的地址组件值。
(三)HTPP事务的时延
1、 如果对URI的主机名最近没有访问,通过DNS解析需要花费时间
2、 TCP连接建立时延。三次握手,多条连接的时延会快速的叠加。
3、 传输请求报文,服务器接收并进行处理。
4、 服务器会送HTTP响应报文。
(四)TCP性能聚焦
影响较大,较常见的TCP相关时延包括:建立握手;慢启动拥塞控制、数据聚集的Nagle算法、用于捎带确认的TCP延迟确认算法、TIME_WAIT时延和端口耗尽。
1、 在建立一条新的连接之前,甚至在发送任意数据之前,TCP软件之间会交换一系列的IP分组,对连接的有关参数进行确认。如果连接只用来传送少量数据,这些交换过程会严重降低HTTP的性能。
第一步,客户端向服务器发送一个小的TCP分组,其中设置一个特殊的SYN标记,说明是一个连接请求。
第二步,服务器如果接受了请求,对一些连接参数进行计算,向客户端回送一个TCP分组,分组中SYN和ACK标记都被置位,说明连接请求已被接受。
第三步,客户端回送一条确认信息,通知连接已经成功建立。现代TCP栈都允许客户端在这个分组中发送数据。304 Not Modified 等小型http事务,在建立连接上耗时可能50%以上。
2、 延迟确认。因特网无法确保可靠的分组传输,TCP实现有自己的确认机制来确保数据的成功传输。
每个TCP段都有一个序列号和数据完整性校验和。接收者收到完好的段时,都会向发送者回送小的确认分组。如果发送者没有在指定的窗口时间内收到确认信息,发送者就认为分组已经被破坏,并重发数据。
由于确认报文很小,所以TCP允许在发往相同方向的输出数据分组中对其进行“捎带”。很多TCP栈都实现了一种“延迟确认”算法。会在一个特定的窗口时间内,将输出确认存放在缓冲区内,以寻找能够捎带它的输出数据分组。如果没有输出数据分组,就将其单独发送。
但是,HTTP具有双峰特征的请求,应答行为降低了捎带信息的可能。通常,延迟确认算法会引入相当大的时延。根据所使用操作系统的不同,可以调整或禁止延迟确认算法。
3、 TCP慢启动。连接会随着时间进行自我“调谐”,起初会限制连接的最大速度,如果数据传输成功,会随着时间的推移提高传输的速度。用于阻止因特网的突然过载和拥塞。
由于这种特性,新打开的连接传输速度会比交换过一定数量数据的连接慢一点。应尽量重用现存连接。
4、 Nagle算法与TCP_NODELAY。TCP有一个数据流接口。可以将任意大小的数据放入TCP栈中,所以如果大量包含极少数据的分组,网络的性能就会严重下降。
Nagle算法试图在发送一个分组之前,将大量TCP数据绑定在一起,提高网络效率。鼓励发送全尺寸的段(LAN上最大尺寸的分组大约是1500字节,在网络中是几百字节)。只有当所有其他分组都被确认之后,Nagle算法才允许发送非全尺寸的分组。
HTTP应用程序常常会在自己的栈中设置参数TCP_NODELAY,禁用此算法,提高性能。
5、 TIME_WAIT累积与端口耗尽
端口耗尽是很严重的问题,当某个TCP端点关闭连接时,会在内存中维护一个小的控制块,用来记录最近所关闭连接的IP地址和端口号。
通常只会维持一小段时间,2分钟左右,以确保在这段时间内不会创建具有相同地址和端口号的新连接。防止来自之前连接的复制分组插入了具有相同连接值的新TCP流中,会破坏TPC数据。
(五)HTTP连接的处理
如果只对连接做简单的串行管理,TCP的连接时延和慢启动会很快叠加起来。更坏的情况,有些浏览器在对象加载完毕之前无法获知对象的尺寸,计算布局位置,在加载完之前,页面无法显示内容。几种现存和新兴的方法可以提高HTTP的连接性能。
1、 并行连接。浏览器可以执行多个HTTP事务。
优势:使连接时延重叠,高效利用带宽,多个组件对象同时显示加载对用户友好。劣势:带宽有限时,每个连接都很慢尤其新打开时,web服务器的性能压力
现状:浏览器使用了并行连接,对同一域名的链接总数限制为一个较小的值,且服务器可以随意关闭超量连接。
2、 持久链接。HTTP/1.1允许设备在事务处理结束之后将TCP连接保持在打开状态。
优势:避免多次的连接时延,和慢启动的拥塞适应,减少了连接数量、性能压力。
劣势:按顺序串行请求,对带宽可能有浪费。
现状:与并行连接结合使用,打开最多两条并行的持久连接。
3、 管道化链接。在持久连接的基础上的优化。
在响应到达之前,可以将多条请求放入队列,顺序发出。
限制:服务器必须按照与请求相同的顺序回送HTTP响应。连接会在任意时刻断开,客户端要能重发所有未完的请求。不应该在管道中发送有副作用非幂等的请求(post等),无法安全的重试。
4、 SPDY会话层协议。Chromium引入的新机制,为了解决网络延迟和安全性问题。
在HTTP2.0的草案中将引入此协议。核心思想是多路复用,使用一个连接来传输网页中的众多资源。HTTP>SYDY>SSL>TCP>IP。
优势:根据请求的优先级,服务器可以优先回复优先的资源。服务器可以在发送网页时,尝试发送一些信息给浏览器,浏览器可以提前知道并决定是否需要下载,甚至,服务求可以主动发送资源。
五、HTTP报文
报文由三部分组成:起始行,首部块,可选包含数据的主体。分为请求报文和响应报文。
请求报文:
<method> <request-URL> <version>
<header>
<entity-body>
响应报文:
<version> <status> <reason-phrase>
<headers>
<entity-body>
(一)请求报文
在请求报文起始行开始位置,客户端希望服务器对资源执行的动作标识。各方法在网络发送并无实质不同,都是HTTP的报文,只是在规范上有所不同,如GET不发送实体,可以在URL后加查询字符串;POST将数据放在数据报文实体中。服务器端根据不同的路由设置来处理对应的报文。
1、 GET方法。最常用的,安全方法,通常用于请求服务器发送某个资源。
2、 HEAD。只返回同样GET方法的首部信息。不会反悔实体的主体部分。可以用来查看对象资源的状态,是否存在,是否有效。
3、 PUT。向服务器写入文档,创建一个由所请求的URL命名的新文档。
4、 POST,起初是用来向服务器输入数据的,通常用来支持HTML的表单。
5、 TRACE,终端服务器会发起一个追踪响应,在主体中携带它收到的原始请求报文,可以查看报文是否被中间实体修改过。缺陷是,要假定中间应用程序对不同类型的请求处理是相同的.
6、 OPTIONS,请求告知服务器对某资源支持的各种功能。
7、 DELETE,请求删除URL指定的资源。
(二)报文首部
可以分为通用、请求、响应、实体、扩展首部。
1、 通用信息性首部
通用缓存首部
2、 请求首部
请求信息性首部,
Accept内容协商首部
条件请求首部
安全请求首部
代理请求首部
3、 响应首部
信息性首部
协商首部
安全响应首部
4、 实体信息性首部
内容首部
实体缓存首部
六、Web的结构组件
代理:接收客户端请求,转发给服务器。反向代理,负载均衡等应用。
缓存:或代理缓存。特殊的HTTP代理服务器,提供文档缓存服务。
网关:特殊上服务器,作为其他服务器的中间实体使用,用在HTTP协议与其他协议之间的转换沟通。
隧道:在连接之间对原始数据进行盲转发的HTTP应用程序。
Agent代理:浏览器,网络爬虫