为了账号安全,请及时绑定邮箱和手机立即绑定

全面解读Http(读书笔记1)

标签:
WebApp

原文:http://fanqieto.top/2017/09/23/%E5%85%A8%E9%9D%A2%E8%A7%A3%E8%AF%BBhttp/
HTTP协议是因特网的多媒体信使。HTTP可以从遍布世界的Web服务器上将这些信息快迅速,便捷,可靠地搬移到人们桌面上的Web浏览器上去。
HTTP协议主要分Web客户端和服务器。其中Web服务器是Web资源的宿主。Web资源可以包含任意媒体类型内容,HTTP协议为了标识各种媒体类型,会给通过Web传输的对象都打上MIME类型的数据标签格式。
<!--more-->

web基础知识
概述HTTP

HTTP协议是因特网的多媒体信使。HTTP可以从遍布世界的Web服务器上将这些信息快迅速,便捷,可靠地搬移到人们桌面上的Web浏览器上去。

HTTP协议主要分Web客户端和服务器。其中Web服务器是Web资源的宿主。Web资源可以包含任意媒体类型内容,HTTP协议为了标识各种媒体类型,会给通过Web传输的对象都打上MIME类型的数据标签格式。(MIME科普:最初设计MIME(Multipurpose Internet Mail Extension,多用途因特网邮件扩展)是为了解决在不同的电子邮件系统之间搬移报文时存在的问题。HTTP随后也采用了它,用他来描述并标记多媒体内容。)

同时,每个web服务器资源都有一个名字去标识,这被称为统一资源标识符(Uniform Resource Identifier)。URI有两种类型,一种是我们常见的统一资源定位符URL,另外一种被称为统一资源名URN。后者仍处于试验阶段,未大范围使用。

web页面可以包含多个对象,如一个页面会包括许多图片,视频,音频等内容。客户端通过向Web服务器发送请求命令来进行事务处理。服务器响应客户端请求,并传送相应数据。

请求和响应报文都有固定的规范。报文由一行一行简单字符串组成的。HTTP报文都是纯文本,而不是二进制代码,所以人们可以很方便的进行读写(但难以解析)。报文分为三部分

  • 起始行 GET /index.html HTTP/1.0
  • 首部字段 每个首部字段包含一个名字和一个值,为了便于解析,两者之间用冒号来分割。首部以一个空行结束。
  • 主体 起始行和首部都是文本形式且都是结构化的,主体则可以包含任意的二进制数据,当然也可以包含文本。

HTTP协议的报文是通过传输控制协议(Transmission Control Protocol,TCP)连接从一个地方搬移到另外一个地方去的。TCP提供了

  • 无差错的数据传输
  • 按序传输 (数据总是会按照发送的顺序到达)
  • 未分段的数据流 (可以在任意时刻以任意尺寸将数据发送出去)

在HTTP客户端向服务器发送报文之前,需要用网际协议(Internet Protocol,IP)地址和端口号在客户端和服务器之间建立一条TCP/IP连接。首先需要将URL进行DNS解析成IP地址,再用IP地址连接Web服务器,默认端口是80。

除了客户端与服务器之外,还有许多比较重要的Web结构组件

  • 代理 位于客户端和服务器之间的HTTP中间实体
  • 缓存 HTTP的仓库,使常用页面的副本可以保存在离客户端更近的地方
  • 网关 连接其他应用程序的特殊Web服务器
  • 隧道 对HTTP通信报文进行盲转发的特殊代理
  • Agent代理 发起自动HTTP请求的半智能Web客户端

B/S 结构定义

浏览器-服务器(Browser/Server)结构,简称B/S结构,与C/S结构不同,其客户端不需要安装专门的软件,只需要浏览器即可,浏览器通过Web服务器与数据库进行交互,可以方便的在不同平台下工作;服务器端可采用高性能计算机,并安装Oracle、Sybase、Informix等大型数据库。B/S结构简化了客户端的工作,它是随着Internet技术兴起而产生的,对C/S技术的改进,但该结构下服务器端的工作较重,对服务器的性能要求更高。

URI (统一资源标志符)

在电脑术语中,统一资源标识符(英语:Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符串。 该种标识允许用户对网络中(一般指万维网)的资源通过特定的协议进行交互操作。URI的最常见的形式是统一资源定位符(URL),经常指定为非正式的网址。更罕见的用法是统一资源名称(URN),其目的是通过提供一种途径。用于在特定的命名空间资源的标识,以补充网址。

URI 文法

URI文法由URI协议名(例如“http”,“ftp”,“mailto”或“file”),一个冒号,和协议对应的内容所构成。特定的协议定义了协议内容的语法和语义,而所有的协议都必须遵循一定的URI文法通用规则,亦即为某些专门目的保留部分特殊字符。

一个uri的例子
paste

MIME

MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式

常见的 MIME 类型有:
paste

HTTP 协议

超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是互联网上应用最为广泛的一种网络协议。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers,URI)来标识。

HTTP 协议是基于请求与响应,具体如下图所示:
paste

HTTP 协议主要特点

  • 简单快速:当客户端向服务器端发送请求时,只是简单的填写请求路径和请求方法即可,然后就可以通过浏览器或其他方式将该请求发送就行了
  • 灵活:HTTP 协议允许客户端和服务器端传输任意类型任意格式的数据对象
  • 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接,采用这种方式可以节省传输时间。(当今多数服务器支持Keep-Alive功能,使用服务器支持长连接,解决无连接的问题)
  • 无状态:无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即客户端发送HTTP请求后,服务器根据请求,会给我们发送数据,发送完后,不会记录信息。(使用 cookie 机制可以保持 session,解决无状态的问题)
http报文

HTTP 请求报文

HTTP 请求报文由请求行、请求头、空行 和 请求体(请求数据) 4 个部分组成
paste

请求实例

GET / HTTP/1.1
Host: www.baidu.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,id;q=0.4
Cookie: PSTM=1490844191; BIDUPSID=2145FF54639208435F60E1E165379255; BAIDUID=CFA344942EE2E0EE081D8B13B5C847F9:FG=1;

请求头

请求头由 key-value 对组成,每行一对,key (键) 和 value (值)用英文冒号 : 分隔。请求头通知服务器有关于客户端请求的信息,典型的请求头有:

  • User-Agent:用户代理信息 - Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 ...
  • Accept:客户端可识别的内容类型列表 - text/html,application/xhtml+xml,application/xml
  • Accept-Language:客户端可接受的自然语言 - zh-CN,zh;q=0.8,en;q=0.6,id;q=0.4
  • Accept-Encoding:客户端可接受的编码压缩格式 - gzip, deflate, sdch, br
  • Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机 - www.baidu.com
  • connection:连接方式
  • close:告诉WEB服务器或代理服务器,在完成本次请求的响应后,断开连接
  • keep-alive:告诉WEB服务器或代理服务器。在完成本次请求的响应后,保持连接,以等待后续请求
  • Cookie:存储于客户端扩展字段,向同一域名的服务端发送属于该域的cookie - PSTM=1490844191; BIDUPSID=2145FF54639208435F60E1E165379255;

空行

最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。

请求体

请求数据不在 GET 方法中使用,而是在 POST 方法中使用。与请求数据相关的最常使用的请求头是 Content-Type和 Content-Length。

HTTP 响应报文

HTTP响应报文由状态行、响应头、空行和响应体4 个部分组成,如下图所示:

paste

响应报文示例

HTTP/1.1 200 OK
Server: bfe/1.0.8.18
Date: Thu, 30 Mar 2017 12:28:00 GMT
Content-Type: text/html; charset=utf-8
Connection: keep-alive
Cache-Control: private
Expires: Thu, 30 Mar 2017 12:27:43 GMT
Set-Cookie: BDSVRTM=0; path=/

状态行

状态行格式: HTTP-Version Status-Code Reason-Phrase CRLF

  • HTTP-Version - HTTP 协议版本
  • Status-Code - 状态码
  • Reason-Phrase - 状态码描述
  • CRLF - 回车/换行符

响应头

响应头由 key-value 对组成,每行一对,key (键) 和 value (值)用英文冒号 : 分隔。响应头域允许服务器传递不能放在状态行的附加信息,这些域主要描述服务器的信息和Request-URI进一步的信息,典型的响应头有:

  • Server:包含处理请求的原始服务器的软件信息
  • Date:服务器日期
  • Content-Type:返回的资源类型 (MIME)
  • Connection:连接方式
    • close:连接已经关闭
    • keep-alive:连接已保持,在等待本次连接的后续请求
  • Cache-Control:缓存控制
  • Expires:设置过期时间
  • Set-Cookie:设置 Cookie 信息

空行

最后一个响应头之后是一个空行,发送回车符和换行符,通知浏览器以下不再有响应头。

响应体

服务器返回给浏览器的响应信息,下面是百度首页的响应体片段:

<!DOCTYPE html>
<!--STATUS OK-->
<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <link rel="icon" sizes="any" mask href="//www.baidu.com/img/baidu.svg">
    <title>百度一下,你就知道</title>
</head>
<body>
  ...
</body>
</html>

HTTP Methods

HTTP 协议的请求方法有:GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT、PATCH、HEAD

HTTP 常用的请求方法:

HTTP Status Code

状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值:

  • 1xx:指示信息 – 表示请求已接收,继续处理
  • 2xx:成功 – 表示请求已被成功接收
  • 3xx:重定向 – 要完成请求必须进行更进一步的操作
  • 4xx:客户端错误 – 请求有语法错误或请求无法实现
  • 5xx:服务器错误 – 服务器未能实现合法的请求
    常见状态代码、状态描述的说明如下:

  • 200 OK:客户端请求成功
  • 204 No Content:没有新文档,浏览器应该继续显示原来的文档
  • 206 Partial Content:客户发送了一个带有Range头的GET请求,服务器完成了它
  • 301 Moved Permanently:所请求的页面已经转移至新的url
  • 302 Found:所请求的页面已经临时转移至新的url
  • 304 Not Modified:客户端有缓冲的文档并发出了一个条件性的请求,服务器告诉客户,原来缓冲的文档还可以继续使用。
  • 400 Bad Request:客户端请求有语法错误,不能被服务器所理解
  • 401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
  • 403 Forbidden:对被请求页面的访问被禁止
  • 404 Not Found:请求资源不存在
  • 500 Internal Server Error:服务器发生不可预期的错误
  • 503 Server Unavailable:请求未完成,服务器临时过载或当机,一段时间后可能恢复正常
连接管理

世界上几乎所有的HTTP通信都是由TCP/IP承载的,TCP/IP是全球计算机及网络设备都在使用的一种常用的分组交换网络分层协议集。客户端应用程序可以打开一条TCP/IP连接,连接到可能运行在世界任何地方的服务器应用程序。

web浏览器通过TCP连接与web服务器进行交互的流程

https://github.com/wujunqi

  • 浏览器利用解析出主机名 github.com
  • 浏览器查询这个主机名的IP地址 192.30.252.122
  • 浏览器获得端口号 80
  • 浏览器发起到192.30.252.122端口80的连接
  • 浏览器向服务器发送一条HTTP GET报文
  • 浏览器从服务器读取HTTP响应报文
  • 浏览器关闭TCP连接

HTTP事务的时延

与建立TCP连接,以及传输请求和响应报文的时间相比,事务处理时间可能是很短的。除非客户端或服务器超载,或正在处理复杂的动态资源,否则HTTP时延就是由TCP网络时延构成的。

HTTP事务时延的有以下几种主要原因

  • 客户端首先需要根据URI确定Web服务器的IP地址和端口号。其中IP地址需要通过DNS解析URL中的主机名获得,这需要花费时间。
  • 客户端向服务器发送TCP连接请求,即著名的”三次握手”。这个值通常很短,但如果有数百个HTTP事务的话,这个值就会快速叠加上去。
  • 因特网传输报文,以及服务器处理请求报文都需要花费时间。
  • web服务器回送HTTP响应也需要时间。
    这些TCP网络时延取决于硬件速度,网络和服务器的负载,请求和响应报文的尺寸,以及客户端和服务器之间的距离。TCP协议的技术复杂性也会对时延产生巨大的影响。

性能聚焦区域

一下是其余一些会对HTTP产生影响,最常见的相关时延

  • TCP连接建立握手

  • TCP慢启动拥塞控制
    • 最初的TCP的实现方式是,在连接建立成功后便会向网络中发送大尺寸的数据包,假如网络出现问题,很多这样的大包会积攒在路由器上,很容易导致网络中路由器缓存空间耗尽,从而发生拥塞。因此现在的TCP协议规定了,新建立的连接不能够一开始就发送大尺寸的数据包,而只能从一个小尺寸的包开始发送,在发送和数据被对方确认的过程中去计算对方的接收速度,来逐步增加每次发送的数据量(最后到达一个稳定的值,进入高速传输阶段。相应的,慢启动过程中,TCP通道处在低速传输阶段),以避免上述现象的发生。这个策略就是慢启动。
  • 数据聚焦的Nagle算法
  • 用于捎带确认的TCP延迟确认算法
  • TIME_WAIT时延和端口耗尽
    • 只有一个服务端和一个web服务器的异常情况下
    • 当某个 TCP 端点关闭 TCP 连接时,会在内存中维护一个小的控制块,用来记录最近所关闭连接的 IP 地址和端口号。这类信息只会维持一小段时间,通常是所估计的最大分段试用期的两倍(称为2MSL,通常为2分钟)左右,以确保在这段时间内不会创建具有相同地址和端口号的新连接。实际上,这个算法可以防止在2分钟内创建、关闭并重新创建2个相同 IP 地址和端口号的连接。

TCP连接建立握手

TCP连接握手需要经过一下几个步骤

  • 客户端的向服务器发送一个小的TCP分组(通常是40-60字节)。这个分组中设置了一个特殊的SYN标记,说明这是一个连接请求。
  • 如果服务器接收了连接,就会对一些连接参数进行计算,并向客户端回送一个TCP分组,这个分组中的SYN和ACK标记都被置位了,说明连接请求已经被接收了。
  • 最后,客户端向服务器回送一条确认信息,通知它连接已成功建立。现代的TCP栈都允许客户端在这个确认分组中发送数据。
  • 如果连接只用来传送少量的数据,这些交换过程就会严重降低HTTP的性能。小的HTTP事务可能会在TCP建立上花费50%或者更多的时间。
    paste

    • SYN:表示连接请求
    • SYN/ACK:表示请求接受
    • 连接只用来传送少量数据、这些交换过程会严重降低http的性能,小的http事务可能在tcp建立上花费50%或更多时间

延迟确认

每个TCP段都有一个序列号和数据完整性校验和。每个段的接收者收到完好的段时,都会向发送者回送小的确认分组。如果发送者没有在指定的窗口时间内收到确认信息,发送者就认为分为已被破坏或损毁,并重发数据。
为了增加确认报文找到同向传输数据分组的可能性,很多TCP栈都实现了一种”延迟确认”算法。延迟确认算法会在一个特定的窗口时间(通常是100~200毫秒)内将输出确认存放在缓冲区中,以寻找能够捎带它的输出数据分组。如果在那个时间段内没有输出数据分组,就讲确认信息放在单独的分组中传送。
通常,延迟确认算法会引入相当大的时延,所以可以调整或者禁止延迟确认算法。

TCP慢启动

TCP数据传输的性能还取决于TCP连接的使用期(age)。TCP连接会随着时间进行自我“调谐”,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度。这种调谐被称为TCP慢启动(slow start),用于防止因特网的突然过载和拥塞。

Nagle算法与TCP_NODELAY

Nagle算法鼓励发送全尺寸(LAN上最大尺寸的分组大约是1500字节,在因特网上是几百字节)的段。只有当所有其他的分组都被确认之后,Nagle才允许发送非全尺寸的分组,如果其他分仍然在传输过程中,就将那部分数据缓存起来。只有当挂起分组被确认,或者缓存中积累了足够发送一个全尺寸分组的数据时,才会将缓存的数据发送出去。
Nagle算法会引发几种HTTP性能问题。首先小的HTTP报文无法填满一个分组,可能会因为等待那些永远不会到来的额外数据而产生时延。其次,Nagle算法与延时确认之间的交互存在问题——Nagle会阻止数据的发送,直到有确认分组抵达为止,但确认分组自身会被延迟确认算法延迟100-200毫秒。
因此,HTTP应用程序常常会在自己的栈中设置参数TCP_NODELAY,禁用Nagle算法,提高性能。

TIME_WAIT累计和端口耗尽

当某个TCP端点关闭TCP连接时,会在内存中维护一个小的控制块,用来记录最近所关闭连接的IP地址和端口号。这类信息会维持一小段时间,以确保在这段时间内不会创建于相同地址和端口号的新连接。
客户端每次连接到服务器上去时,都会获得一个新的端口号,以实现连接的唯一性。但由于可用的源端口数量有限,因此会出现端口耗尽的情况。就会无法建立新的连接。
解决办法:增加客户端负载生成机器的数量,或者确保客户端和服务器在循环使用几个虚拟的IP地址以增加更多的连接组合。

HTTP连接的处理

HTTP允许在客户端和最终的源端服务器之间存在一串HTTP中间实体(代理,高速缓存等)。可以从客户端开始,逐跳地将HTTP报文经过这些中间设备,转发到源端服务器上去(或者进行反向传输)。

Connection首部

在某些情况下,两个相邻的HTTP应用程序会为它们共享的连接应用一组选项。HTTP的Connection首部字段中有一个由逗号分隔的连接标签列表,这些标签为此连接指定了一些不会传播到其他连接中去的选项。
Connection首部可以承载3种不同类型的标签

HTTP首部字段名,列出了只与此连接有关的首部
任意标签值,用于描述此连接的非标准选项
值close,说明操作完成之后需关闭这条持久连接
串行事务处理时延

如果支队连接进行简单的管理,TCP的性能时延可能会叠加起来。串行加载的另外一个缺点是,有些浏览器在对象加载完毕之前无法获知对象的尺寸,而且它们可能需要尺寸信息来决定将对象放在屏幕的什么位置上,所以在加载了足够多的对象之前,无法在屏幕上显示任何内容。

以下为4种提高HTTP连接性能的技术。

  • 并行连接:

    通过多条TCP连接发起并发的HTTP请求HTTP允许客户端打开多条连接,并行地执行多个HTTP事务。并行连接可以提高符合页面的传输速度,但并行连接也有一些缺点:

    • 每个事务都会打开/关闭一条新的连接,好耗费时间和带宽
    • 由于TCP慢启动特性的存在,每条新连接的性能会有所降低
    • 可打开的并行连接数量实际上是有限的
  • 持久连接 重用TCP连接,以消除连接及关闭时延:

    Web客户端经常会打开到同一个站点的连接。因此,初始化了对某服务器的HTTP请求的应用程序很可能会在不久的将来对那台服务器发起更多的请求。这种性质被称为站点局部性。因此,HTTP/1.1允许HTTP设备在事务处理结束之后将TCP连接保持在打开状态,以便为将来的HTTP请求重用现存的连接。在事务处理结束之后仍然保持在打开状态的TCP连接被称为持久连接。非持久连接会在每个事务结束之后关闭。持久连接会在不同事务之间保持打开状态,直到客户端或服务器决定将其关闭为止。重用已对目标服务器打开的空闲持久连接,就可以避开缓慢的连接建立阶段。而且,已经打开的连接还可以避免慢启动的拥塞适应阶段,以便更快速地进行数据的传输。持久连接有一些比并行连接更好的地方。持久连接降低了时延和连接建立的开销,将连接保持在已调谐状态,而且减少了打开连接的潜在数量。(持久连接有两种类型:比较老的HTTP/1.0+ “keep-alive”连接,以及现代的HTTP/1.1 “persistent”连接)并行连接与持久连接配合使用可能是最高效的方式。

  • 管道化连接, 通过共享的TCP连接发起并发的HTTP请求:
    允许在持久连接上可选的使用请求管道,这是相对于keep-alive连接的又一性能优化。在响应到达之前,可以将多条请求放入队列。当第一条请求通过网络流向地球另一端的服务器时,第二条和第三条请求也可以开始发送了。在高时延网络条件下,这样做可以降低网络的环回时间。
  • 复用的连接 交替传送请求和响应报文 (实验阶段)

点击查看更多内容
2人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
PHP开发工程师
手记
粉丝
8992
获赞与收藏
336

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消