HTTP协议优化分析

HTTP协议是互联网中陈旧而又炙手可热的规范,http报文结构及性能优化成为重点。

URL结构

HTTP URL结构分为三部分:

方案/scheme(http)、服务器位置/host(www.domain.com)、资源路径/path(/aaa/bbb/cccc.html)。

HTTP报文

HTTP报文是HTTP应用程序间传送的数据块,发送者与接收者间存在一种报文流动的概念,发送者为上游(upstream),接收者为下游(downstream),所有报文都向下游流动。(此处并无Server与Client概念)。

报文结构

起始行(start line)、首部/报文头(header)、主体(body)

报文分类

HTTP报文分为两类:

请求报文与响应报文。

两者报文结构相同,区别在于起始行语法有所不同。

HTTP请求报文

起始行

HTTP请求报文起始行由三部分组成:

method(请求方式)、request-url(资源标识)、version(http版本),也被为请求行。

HTTP响应报文

起始行

HTTP响应报文起始行由三部分构成:

version、status(状态码)、reason-phrase(状态的可读版本,便于阅读),称为响应行。

HTTP报文头

HTTP报文头由零或多个键值对(key:value)组成。

键值对

HTTP头部键值对除了HTTP规范定义,可自定义。

格式:key:val 空格或tab

HTTP报文分界线

Http报文头(header)与主体(body)间的分界线为一个CRLF(空行)。

HTTP报文主体

主体(body)包含一个由任意数据组成的数据块。

HTTP Method

GET、HEAD

GET、HEAD为行为安全的方法。

具体的行为实现不应修改服务端内容,两者都是向服务发起请求,GET要求返回资源,HEAD只返回首部(header),两者header在实现上应保持一致。

PUT、POST

PUT、POST为向服务端写入数据。

PUT语义要求服务器以URL为标识(命名),以主体(boby)为内容,在服务器创建一个新文档(已存在则覆盖),POST则通常以form表单将数据发送到服务器,由服务器决定数据去向。

HTTP TRACE

TRACE被用于跟踪请求过程中,各个环节对HTTP原始请求作出的修改,将修改后的内容(服务器端接收到内容的精确副本)作为响应主体(boby)返回,http trace方法通常出现在”闭环“诊断场景中。

HTTP OPTIONS

OPTIONS用于让服务器告知支持服务端哪些method。

HTTP DELETE

DELETE请求服务器删除指定资源,HTTP规范允许服务器以不通知客户端的方式撤销请求。

HTTP响应状态码

W3C HTTP状态码说明

http信息提示码

100~199已定义范围100~101,信息提示。

http成功状态码

200~299已定义范围200~206,成功。

HTTP 200 请求已成功,200响应中发送的有效负载取决于请求方法。

HTTP 201 Created,成功状态响应代码,请求已成功并已创建资源,在发回该响应前有效地创建新资源,并在消息正文中返回新资源。

HTTP 202 该请求已被接受处理,但处理尚未完成。

HTTP 203非权威信息,实体标头中返回的元信息不是从源服务器可用的权威集,而是从本地或第三方副本收集。

HTTP 204无内容,服务器已完成请求但不需要返回实体主体,且可能希望返回更新的元信息。

HTTP 205重置内容,服务器已完成请求,用户代理应该重置文档视图。

HTTP 206部分内容,服务器已完成对资源的部分GET请求。

http重定向码

300~399已定义范围300~305,重定向。

HTTP 301重定向-永久性移走。

HTTP 302重定向-代表暂时性转移(Temporarily Moved )。

HTTP 303和302状态码功能相同,但303只能用get方法获取资源。

HTTP 304 Not Modified客户端重定向响应代码表示无需重新传输所请求资源。

HTTP 305 CheckUpDown,Web服务器认为URL应该重定向到另一个URL - “代理”。

http客户端错误码

400~499已定义范围400~415,客户端错误。

HTTP 401 错误 - 未授权: (Unauthorized) 。

HTTP 403 Forbidden - 拒绝访问。

HTTP 404 Web服务器找不到所请求文件或脚本,检查URL以确保路径正确。

HTTP 405 不允许此方法,对于请求所标识资源,不允许使用请求行中所指定方法。

HTTP 406 不可接受,此请求所标识资源只能生成内容特征为“不可接受”的响应实体。

HTTP 407 需要代理身份验证,必须验证此代理服务器。

HTTP 412 在服务器上测试前提条件时,部分请求标题字段中所给定的前提条件评估为FALSE。

HTTP 414 Request-URI 太长,服务器拒绝服务此请求。

http服务器错误码

500~599已定义范围500~505,服务器错误。

HTTP 500 服务器内部错误,一般程序上为程序错误。

HTTP 501 未实现 (Not implemented),Web 服务器不理解或不支持HTTP请求。

HTTP 502 Bad Gateway,大多为上游服务器和网关/代理以不同协议交换数据(不一致)。

HTTP 503 Service Unavailable,服务不可用,暂时超载或临时维护,Web服务器目前无法处理HTTP请求。

HTTP 504  Gateway timeout,网关超时,意味着上游服务器已关闭(不响应网关 / 代理)。

HTTP 505 HTTP Version Not Supported,服务器不支持或拒绝支持请求消息中使用的HTTP版本。

TCP/IP协议

HTTP over TCP over IP

HTTP传送一条报文,以流方式将数据传给TCP/IP程序,TCP/IP会将数据流分成”段“,将”段“封装在IP分组中,通过因特网传输。

IP分组

每个TCP“段”都由IP分组承载,从一个IP地址发送到另一个IP地址。IP分组中包括:

IP分组头部:源、目标IP地址,长度和其他标记。

TCP段头部:TCP端口号、TCP控制标记、数据排序和用于完整性检查的数值。

TCP数据块。

TCP连接标识

在操作系统中,一个TCP连接标识由四部分构成:

源IP地址、源端口号、目标IP地址、目标端口号

四部分构成一条唯一的TCP连接标识,以文件形式存放在操作系统中。

TCP连接握手步骤

1、客户端向服务器发送一个TCP分组,分组中设置一个特殊的SYN标记。

2、服务器接受连接,对一些连接参数进行计算,并向客户端回送一个TCP分组,分组中包含被置位的SYN和ACK。

3、客户端向服务器回送一条确认信息,通知连接已建立(通常可在当前确认请求中稍带业务数据)。

HTTP性能

TCP连接握手

HTTP事务在建立TCP连接上可能会花费50%的时间,如何重用现存连接,减小这种时延造成的影响,成为优化的焦点。

延迟确认

网络传输不能保证数据的到达率,TCP需自己实现数据完整性及传输成功的校验,因此,需要有确认报文,确认报文本身很小,为了有效利用网络,可在发送确认信息时“稍上”同向输出数据,为能够等到同向输出数据,确认信息通常会延迟100~200毫秒后发出。

合理调整延迟确认算法成为改善此问题的焦点。

TCP慢启动

TCP数据传输为防止网络突然过载和拥堵,不会一次将所有分组都发送出去,在发送一个分组成功并确认后,接着会发送两个分组,成功后会发送四个分组,以此类推的将数据分组传出去。

新连接会比已经交换过数据的连接慢,所以,可使用工具重用现存连接提升传输性能,HTTP“持久连接”属于此范畴。

Nagle算法

应用程序可将任意大小的数据放入TCP栈中,而每个TCP“段”头部和标记部分至少占40个字节,若用大量TCP发送包含较少数据的分组会很浪费,因此,引入Nagle算法。

Nagle算法在等待上一个分组确认信息过程中,将新进的多个数据分组,重新“打包”成更大数据分组等待发送。

当上一个数据分组的确认信息回来时,或等待发送的数据分组是一个全尺寸(大约1500字节)数据分组时,才会发起新一轮的数据发送。

Nagle算法引发两个新的性能问题:

1、小报文无法填满一个数据分组时,而确认信息又没有回来,此时会一直等待额外数据的到来。

2、与延迟确认机制的冲突,nagle算法收到确认信息前,不会发送新的数据分组,确认信息会被延迟确认算法延迟100~200毫秒,加剧了性能问题。

如果向TCP写入的都是大块数据,禁用Nagle算法会提高性能。

TIME_WAIT时延和端口耗尽

当TCP连接关闭时,内存中仍会为这个连接短暂维护一个小的控制块,此算法防止在两分钟内同一个客户端创建、关闭、重新创建TCP连接的问题。

在服务端可创建多少个TCP连接标识文件,受限于操作系统中一个目录允许的文件数

另一问题则是客户端在作基准测试时,客户端所在机器会因为需要创建唯一性的TCP连接而导致端口耗尽。

这些场景下考虑TIME_WAIT是有意义的。

HTTP Header Connection属性

当客户端与服务器端间存在一些中间实体(如:代理服务器、高速缓存等)。

客户端/服务器在header中发送的key:value若不想被最终接收端看到,可通过Connection属性指定具体key,执行剔除操作。如:

Server发送的header中包含键值:[a:1 b:3 c:5 Connection:a,c],经代理服务器转发到Client时,Client收到的header中只包含[b:3]。a、c被Connection属性剔除。

Connection键值对在现代代理服务器中是一个不会被连续转发的存在,A发送请求给B(代理服务器),B收到header中包含的Connection键值对,再转发给C时,Connection的键值会影响header中的键值。

在header中不能被代理转发或作为响应“头部”内容的包括:

Proxy-Authenticate、Proxy-Connection、Transfer-Encoding、Upgrade