cJava Web知识Java, lnc.

Http 长连接、短连接、长轮询、短轮询

2018-05-29  本文已影响713人  燕京博士

HTTP概述

HTTP协议用于约定服务端(如Web服务器Tomcat、IIS)和客户端(如浏览器、APP)通信的消息格式和响应方式。了解HTTP协议内容有助于优化Http请求,如断点下载、多线程下载、防盗链等功能的实现。HTTP协议是建立在TCP协议之上的,理论上只要有一个Socket就能够实现Http消息的请求,实现比如HttpClient、UrlConnection的请求操作。只要有一个SocketServer就能够实现Http消息的响应,实现比如Tomcat、IIS等Web服务器的功能,比如在手机上部署网站,用户可以在浏览器端访问同一网络下的手机部署的站点。

HTTP请求协议详解

HTTP1.1的请求协议报文结构如下图,大体上可以分为三块,即请求行、头部、消息主体。

HTTP请求协议报文结构

请求行

请求行包含HTTP请求方法、请求的URL、HTTP协议版本三个内容,它们之间以空格间隔,并以回车+换行结束。

HTTP请求方法有下面几种,常用的有GET、POST请求。

请求头部

头部可以分成三个部分,为常用头域、请求头域、实体头域。其中常用头域和实体头域部分内容在响应协议部分也有相同的定义。

常用头域
常用头域名称 作用描述
Cache-Control 缓存控制
Connection HTTP 1.1默认是支持长连接的(Keep-Alive),如果不希望支持长连接则需要在此域中写入close
Date 表明消息产生的日期和时间
Pragma
Trailer
Transfer-Encoding 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式
Upgrade 给出了发送端可能想要”升级”使用的新版本或协议
Via 显示了报文经过的中间节点(代理、网关)
Warning
请求头域
请求头域名称 作用描述
Accept 指明请求端可以接受处理的媒体类型
Accept-Charset 指明请求端可以接受的字符集
Accept-Encoding 指明请求端可以接受的编码格式
Authorization 授权
Expect 允许客户端列出某请求所要求的服务器行为
From 提供了客户端用户的E-mail地址
Host 指明请求端的网络主机和端口号
If-Match 服务端在响应头部里面返回ETag信息,客户端请求时在头部添加If-Match(值为响应的ETag),服务端接收后判断ETag是否相同,若相同则处理请求,否则不处理请求。
If-Modified-Since 客户端在请求某一资源文件时,在头部加上If-Modified-Since(值为该资源文件的最后修改时间),服务端接收后将客户端上报的修改时间与服务器存储的文件的最后修改时间做对比,如果相同,说明资源文件没有更新,返回304状态码,告诉客户端使用原来的缓存文件。否则返回资源内容。
If-None-Match 服务端在响应头部里面返回ETag信息,客户端请求时在头部添加If-None-Match(值为响应的ETag),服务端接收后判断ETag是否相同,若相同,说明资源没有更新,返回304状态码,告诉客户端使用原来的缓存文件。否则返回资源内容。
If-Range 该头域与Range头域一起使用,服务端在响应头部里面返回ETag信息,客户端请求时在头部添加If-Range(值为响应的ETag),服务端接收后判断ETag是否相同,若相同,则返回状态码206,返回内容为Range指定的字节范围。若不相同,则返回状态码200,返回内容为整个实体。
If-Unmodified-Since 客户端在请求某一资源文件时,在头部加上If-Modified-Since(值为该资源文件的最后修改时间),端接收后将客户端上报的修改时间与服务器存储的文件的最后修改时间做对比,如果相同,则返回资源内容,如果不相同则返回状态码412。
Max-Forwards 配合TRACE、OPTIONS方法使用,限制在通往服务器的路径上的代理或网关的数量。
Proxy-Authorization 代理授权
Range 表示客户端向服务端请求指定范围的字节数量:Range:bytes=0-500表示请求第1个到第501个的字节数量。Range:bytes=100-表示请求第101到文件倒数第一个字节的字节数量。Range:bytes=-500表示请求最后500个字节的数量。Range可以同时指定多组(Range:bytes=500-600,601-999)。并不是所有的服务端都支持字节范围请求的,如果支持字节范围请求,服务端会返回状态码206,若不支持则会返回200,客户端需要根据状态码来判断服务端是否支持字节范围操作。此域可用于断点下载,即在断点处请求后面的内容,也可用于多线程下载同一个文件,每个线程负责一个文件的一部分下载工作,多个线程协同完成整个文件的下载。
Referer 用于指定客户端请求的来源,是从搜索引擎过来的?还是从其它网站链接过来的?服务器根据此域,有时可以用做防盗链处理,不在指定范围内的来源,统统拒绝。
TE 指明客户端可以接受哪些传输编码。
实体头域
实体头域名称 作用描述
Allow 指明被请求的资源所支持的方法,如GET、HEAD、PUT
Content-Encoding 指明实体内容所采用的编码方式
Content-Language 指明实体内容使用的语言
Content-Length 指明请求实体的字节数量
Content-Location 可以用来为实体提供对应资源的位置
Content-MD5 指定实体内容的MD5,用于内容的完整性校验(base64的128位MD5)
Content-Range
Content-Type 指定实体的媒体类型
Expires 指明实体的过期时间
Last-Modified 指明实体最后被修改的时间

HTTP响应协议详解

HTTP1.1的响应协议报文结构如下图,大体上可以分为三块,即状态行、头部、消息主体。

HTTP响应报文结构

状态行

状态行包含HTTP协议版本、状态码、原因短语三个内容,它们之间以空格间隔,并以回车+换行结束。

状态码由三位数字组成,第一位数字定义了响应类型,主要有如下五种类型的状态码

状态码类型 作用描述
1xx 报告(请求被接收,继续处理)
2xx 成功(请求被成功的接收并处理)
3xx 重发
4xx 客户端出错(客户端错误的协议格式和不能处理的请求)
5xx 服务器出错(服务器无法完成有效的请求处理)

状态码和对应的原因短语详细描述

状态码 原因短语 中文描述
100 Continue 继续
101 Switching Protocols 切换协议
200 OK 成功
201 Created 已创建
202 Accepted 接受
203 Non-Authoritative information 非权威信息
204 No Content 无内容
205 Reset Content 重置内容
206 Partial Content 部分内容
300 Multiple Choices 多个选择
301 Moved Permanently 永久移动
302 Found 发现
303 See Other 见其它
304 Not Modified 没有改变
305 Use Proxy 使用代理
307 Temporary Redirect 临时重发
400 Bad Request 坏请求
401 Unauthorized 未授权的
402 Payment Required 必需的支付
403 Forbidden 禁用
404 Not Found 没有找到
405 Method Not Allowed 方法不被允许
406 Not Acceptable 不可接受的
407 Proxy Authentication Required 需要代理验证
408 Request Timeout 请求超时
409 Confilict 冲突
410 Gone 不存在
411 Length Required 长度必需
412 Precondition Failed 先决条件失败
413 Request Entity Too Large 请求实体太大
414 Request-URI Too Long 请求URI太长
415 Unsupported Media Type 不支持的媒体类型
416 Requested Range Not Satisfiable 请求范围不被满足
417 Expectation Failed 期望失败
500 Internal Server Error 内部服务器错误
501 Not Implemented 服务端没有实现
502 Bad Gateway 坏网关
503 Service Unavailable 服务不能获得
504 Gateway Timeout 网关超时
505 HTTP Version Not Supported HTTP协议版本不支持

响应头域

响应头域名称 作用描述
Accept-Ranges 服务器向客户端指明服务器对范围请求的接受度
Age 从原始服务器到代理缓存形成的估算时间(以秒计,非负)
ETag 实体标签
Location 指定重定向的URI
Proxy-Autenticate 它指出认证方案和可应用到代理的该URL上的参数
Retry-After 如果实体暂时不可取,通知客户端在指定时间之后再次尝试
Server 指明服务器用于处理请求的软件信息
Vary 告诉下游代理是使用缓存响应还是从原始服务器请求
WWW-Authenticate 表明客户端请求实体应该使用的授权方案

参考资料

Http协议部分讲解

Http协议官方文档

HTTP 2.0 协议详解

一、HTTP 2.0:改进传输性能

HTTP 2.0 的主要目标是改进传输性能,实现低延迟和高吞吐量。从另一方面看,HTTP 的高层协议语义并不会因为这次版本升级而受影响。所有HTTP 首部、值,以及它们的使用场景都不会变。

现有的任何网站和应用,无需做任何修改都可以在HTTP 2.0 上跑起来。不用为了利用HTTP 2.0 的好处而修改标记。HTTP 服务器必须运行HTTP 2.0 协议,但大部分用户都不会因此而受到影响。

二、HTTP2.0历史及其与SPDY的渊源

SPDY 是谷歌开发的一个实验性协议,于2009 年年中发布,主要目标是通过解决HTTP 1.1 中广为人知的一些性能限制,来减少网页的加载延迟

SPDY协议设定的目标

注:为了达到降低50% 页面加载时间的目标,SPDY 引入了一个新的二进制分帧数据层,以实现多向请求和响应、优先次序、最小化及消除不必要的网络延迟,目的是更有效地利用底层TCP 连接;

HTTP-WG(HTTP Working Group)在2012 年初把HTTP 2.0提到了议事日程,吸取SPDY 的经验教训,并在此基础上制定官方标准

三、HTTP2.0深入探究

HTTP/2.0 应该满足如下条件:

HTTP 2.0 致力于突破上一代标准众所周知的性能限制,但它也是对之前1.x 标准的扩展,而非替代。之所以要递增一个大版本到2.0,主要是因为它改变了客户端与服务器之间交换数据的方式,HTTP 2.0 增加了新的二进制分帧数据层

四、HTTP2.0设计和技术目标

HTTP/2.0 通过支持首部字段压缩和在同一连接上发送多个并发消息,让应用更有效地利用网络资源,减少感知的延迟时间。而且,它还支持服务器到客户端的主动推送机制。

HTTP2.0二进制分帧简介

建立HTTP2.0连接后,客户端与服务器会通过交换帧来通信,帧是基于这个新协议通信的最小单位。所有帧都共享一个8字节的首部,其中包含帧的长度、类型、标志,还有一个保留位和一个31位的流标识符。

!###](https://img.haomeiwen.com/i5776456/a46b8dcd2343375e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

针对HTTP2.0的优化建议

TCP/IP
TCP/IP是个协议组,可分为三个层次:网络层、传输层和应用层。
在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。
在传输层中有TCP协议与UDP协议。
在应用层有:TCP包括FTP、HTTP、TELNET、SMTP等协议
UDP包括DNS、TFTP等协议
短连接
连接->传输数据->关闭连接
HTTP是无状态的,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。
也可以这样说:短连接是指SOCKET连接后发送后接收完数据后马上断开连接。

长连接
连接->传输数据->保持连接 -> 传输数据-> 。。。 ->关闭连接。
长连接指建立SOCKET连接后不管是否使用都保持连接,但安全性较差。

http的长连接
HTTP也可以建立长连接的,使用Connection:keep-alive,HTTP 1.1默认进行持久连接。HTTP1.1和HTTP1.0相比较而言,最大的区别就是增加了持久连接支持(貌似最新的 http1.0 可以显示的指定 keep-alive),但还是无状态的,或者说是不可以信任的。

什么时候用长连接,短连接?
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。

而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。

总之,长连接和短连接的选择要视情况而定。
发送接收方式
1、异步
报文发送和接收是分开的,相互独立的,互不影响。这种方式又分两种情况:
(1)异步双工:接收和发送在同一个程序中,由两个不同的子进程分别负责发送和接收
(2)异步单工:接收和发送是用两个不同的程序来完成。
2、同步
报文发送和接收是同步进行,既报文发送后等待接收返回报文。 同步方式一般需要考虑超时问题,即报文发出去后不能无限等待,需要设定超时时间,超过该时间发送方不再等待读返回报文,直接通知超时返回。

在长连接中一般是没有条件能够判断读写什么时候结束,所以必须要加长度报文头。读函数先是读取报文头的长度,再根据这个长度去读相应长度的报文。

Socket是什么

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
[图片上传失败...(image-bfb4aa-1527588784406)]

通信过程:
[图片上传失败...(image-90d03b-1527588784405)]

主机 A 的应用程序要能和主机 B 的应用程序通信,必须通过 Socket 建立连接,而建立 Socket 连接必须需要底层 TCP/IP 协议来建立 TCP 连接。建立 TCP 连接需要底层 IP 协议来寻址网络中的主机。我们知道网络层使用的 IP 协议可以帮助我们根据 IP 地址来找到目标主机,但是一台主机上可能运行着多个应用程序,如何才能与指定的应用程序通信就要通过 TCP 或 UPD 的地址也就是端口号来指定。这样就可以通过一个 Socket 实例唯一代表一个主机上的一个应用程序的通信链路了。

建立通信链路
当客户端要与服务端通信,客户端首先要创建一个 Socket 实例,操作系统将为这个 Socket 实例分配一个没有被使用的本地端口号,并创建一个包含本地和远程地址和端口号的套接字数据结构,这个数据结构将一直保存在系统中直到这个连接关闭。在创建 Socket 实例的构造函数正确返回之前,将要进行 TCP 的三次握手协议,TCP 握手协议完成后,Socket 实例对象将创建完成,否则将抛出 IOException 错误。
与之对应的服务端将创建一个 ServerSocket 实例,ServerSocket 创建比较简单只要指定的端口号没有被占用,一般实例创建都会成功,同时操作系统也会为 ServerSocket 实例创建一个底层数据结构,这个数据结构中包含指定监听的端口号和包含监听地址的通配符,通常情况下都是“*”即监听所有地址。之后当调用 accept() 方法时,将进入阻塞状态,等待客户端的请求。当一个新的请求到来时,将为这个连接创建一个新的套接字数据结构,该套接字数据的信息包含的地址和端口信息正是请求源地址和端口。这个新创建的数据结构将会关联到 ServerSocket 实例的一个未完成的连接数据结构列表中,注意这时服务端与之对应的 Socket 实例并没有完成创建,而要等到与客户端的三次握手完成后,这个服务端的 Socket 实例才会返回,并将这个 Socket 实例对应的数据结构从未完成列表中移到已完成列表中。所以 ServerSocket 所关联的列表中每个数据结构,都代表与一个客户端的建立的 TCP 连接。

备注:
Windows 下单机最大TCP连接数
调整系统参数来调整单机的最大TCP连接数,Windows 下单机的TCP连接数有多个参数共同决定:
以下都是通过修改注册表[HKEY_LOCAL_MACHINE \System \CurrentControlSet \Services \Tcpip \Parameters]

**1.最大TCP连接数 ** TcpNumConnections
2.TCP关闭延迟时间 TCPTimedWaitDelay (30-240)s
3.最大动态端口数 MaxUserPort (Default = 5000, Max = 65534) TCP客户端和服务器连接时,客户端必须分配一个动态端口,默认情况下这个动态端口的分配范围为 1024-5000 ,也就是说默认情况下,客户端最多可以同时发起3977 Socket 连接
4.最大TCB 数量 MaxFreeTcbs
系统为每个TCP 连接分配一个TCP 控制块(TCP control block or TCB),这个控制块用于缓存TCP连接的一些参数,每个TCB需要分配 0.5 KB的pagepool 和 0.5KB 的Non-pagepool,也就说,每个TCP连接会占用 1KB 的系统内存。
非Server版本,MaxFreeTcbs 的默认值为1000 (64M 以上物理内存)Server 版本,这个的默认值为 2000。也就是说,默认情况下,Server 版本最多同时可以建立并保持2000个TCP 连接。
5. 最大TCB Hash table 数量 MaxHashTableSize TCB 是通过Hash table 来管理的。
这个值指明分配 pagepool 内存的数量,也就是说,如果MaxFreeTcbs = 1000 , 则 pagepool 的内存数量为 500KB那么 MaxHashTableSize 应大于 500 才行。这个数量越大,则Hash table 的冗余度就越高,每次分配和查找 TCP 连接用时就越少。这个值必须是2的幂,且最大为65536.

IBM WebSphere Voice Server 在windows server 2003 下的典型配置
MaxUserPort = 65534 (Decimal)
MaxHashTableSize = 65536 (Decimal)
MaxFreeTcbs = 16000 (Decimal)
这里我们可以看到 MaxHashTableSize 被配置为比MaxFreeTcbs 大4倍,这样可以大大增加TCP建立的速度

短连接和长连接

  1. 短连接:每次Http请求都会建立Tcp连接,管理容易

  2. 长连接:只需要建立一次Tcp连接,以后Http请求重复使用同一个Tcp连接,管理难


    这里写图片描述

    HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包、不四次握手),等待在同域名下继续用这个通道传输数据;相反的就是短连接
    如果服务器没有告诉客户端超时时间也没关系,服务端可能主动发起四次握手断开TCP连接,客户端能够知道该TCP连接已经无效;另外TCP还有心跳包来检测当前连接是否还活着,方法很多,避免浪费资源。

在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。

长连接和短连接的产生在于client和server采取的关闭策略,具体的应用场景采用具体的策略,没有十全十美的选择,只有合适的选择

应用场景区别:

  1. 一般长连接(追求实时性高的场景)用于少数client-end to server-end的频繁的通信,例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。
  2. 而像WEB网站的http服务一般都用短链接(追求资源易回收场景),因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源

短轮询和长轮询

和短连接和长连接有本质区别
1. 短轮询:重复发送Http请求,查询目标事件是否完成,优点:编写简单,缺点:浪费带宽和服务器资源
2. 长轮询:在服务端hold住Http请求(死循环或者sleep等等方式),等到目标时间发生,返回Http响应。优点:在无消息的情况下不会频繁的请求,缺点:编写复杂

上一篇下一篇

猜你喜欢

热点阅读