若转载教程,请注明出自SW-X框架官方文档

一、HTTP长连接、短连接究竟是什么?

1、HTTP协议与TCP/IP协议的关系

HTTP的长连接和短连接本质上是TCP长连接和短连接。
HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。
IP协议主要解决网络路由和寻址问题,
TCP协议主要解决如何在IP层之上可靠地传递数据包,使得网络上接收端收到发送端所发出的所有包,并且顺序与发送顺序一致。
TCP协议是可靠的、面向连接、操控监听连接的。

2、如何理解HTTP协议是无状态的

HTTP协议是无状态的,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。
也就是说,打开一个服务器上的网页和上一次打开这个服务器上的网页之间没有任何联系。
HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。

3、什么是长连接、短连接?

在HTTP/1.0中默认使用短连接。
也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。
当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),
每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。
而从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头加入这行代码:
Connection:keep-alive
image.png
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,
客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。
Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。
实现长连接需要客户端和服务端都支持长连接。
HTTP协议的长连接和短连接,实质上就是TCP协议的长连接和短连接。

4、什么是TCP连接?

当网络通信时采用TCP协议时,在真正的读写操作之前,客户端与服务器端之间必须建立一个连接,
当读写操作完成后,双方不再需要这个连接时可以释放这个连接。
连接的建立依靠“三次握手”,
而释放则需要“四次握手”,
所以每个连接的建立都是需要资源消耗和时间消耗的。
经典的三次握手建立连接示意图:
image.png
经典的四次握手关闭连接示意图:
image.png

5、什么是TCP短连接?

模拟一下TCP短连接的情况:
client向server发起连接请求,server接到请求,然后双方建立连接。
client向server发送消息,server回应client,然后一次请求就完成了。
这时候双方任意都可以发起close操作,不过一般都是client先发起close操作。
上述可知,短连接一般只会在 client/server间传递一次请求操作。
短连接的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段。
client:用户server:服务器

6、什么是TCP长连接?

我们再模拟一下长连接的情况:
client向server发起连接,server接受client连接,双方建立连接,
client与server完成一次请求后,它们之间的连接并不会主动关闭,
后续的读写操作会继续使用这个连接。
TCP的保活功能主要为服务器应用提供。
(保活:是指双方一直保持连接通讯,检测任意一方是否已经下线或丢包)。
如果客户端已经消失而连接未断开,则会使得服务器上保留一个半开放的连接,
而服务器又在等待来自客户端的数据,此时服务器将永远等待客户端的数据。
保活功能就是试图在服务端器端检测到这种半开放的连接。
如果一个给定的连接在两小时内没有任何动作,服务器就向客户发送一个探测报文段,
根据客户端主机响应探测4个客户端状态:
1、客户主机依然正常运行,且服务器可达。
此时客户的TCP响应正常,服务器将保活定时器复位。
2、客户主机已经崩溃,并且关闭或者正在重新启动。
上述情况下客户端都不能响应TCP。
服务端将无法收到客户端对探测的响应。
服务器总共发送10个这样的探测,每个间隔75秒。
若服务器没有收到任何一个响应,它就认为客户端已经关闭并终止连接。
3、客户端崩溃并已经重新启动。
服务器将收到一个对其保活探测的响应,这个响应是一个复位,使得服务器终止这个连接。
4、客户机正常运行,但是服务器不可达。这种情况与第二种状态类似。

7、长连接和短连接的优缺点

由上可以看出,长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。
对于频繁请求资源的客户端适合使用长连接。
在长连接的应用场景下,client端一般不会主动关闭连接,当client与server之间的连接一直不关闭,随着客户端连接越来越多,server会保持过多连接。
这时候server端需要采取一些策略,如关闭一些长时间没有请求发生的连接,这样可以避免一些恶意连接导致server端服务受损;
如果条件允许则可以限制每个客户端的最大长连接数,这样可以完全避免恶意的客户端拖垮整体后端服务。
短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。
但如果客户请求频繁,将在TCP的建立和关闭操作上浪费较多时间和带宽。
长连接和短连接的产生在于client和server采取的关闭策略。
不同的应用场景适合采用不同的策略。
由上可以看出,长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。
对于频繁请求资源的客户来说,较适用长连接。
不过这里存在一个问题,存活功能的探测周期太长,还有就是它只是探测TCP连接的存活,属于比较斯文的做法,遇到恶意的连接时,保活功能就不够使了。
在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,
Client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,
这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致server端服务受损;
如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。
长连接和短连接的产生在于client和server采取的关闭策略,具体的应用场景采用具体的策略,没有十全十美的选择,只有合适的选择。

8、长连接和短连接的操作过程

短连接的操作步骤是:
建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接
长连接的操作步骤是:
建立连接——数据传输…(保持连接)…数据传输——关闭连接

9、什么时候用长连接、短连接?

长连接多用于操作频繁,点对点的通讯,而且连接数不能太多的情况下,否则会极其消耗内存。
每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,
所以每个操作完后都不断开,下一次处理时直接发送数据包就OK了,不用再次建立TCP连接。
例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket创建也是对资源的浪费。
而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,
而在一些用户在线时间较短的应用上,用短连接会更省一些资源,
所以并发量大,但每个用户在线时间较短的情况下使用短连接。
长连接一般使用在长时间在线,并且需要持久跟进业务的应用,诸如:即时通讯业务,聊天室、APP的消息推送、WEB端后台的操作消息提醒等。

二、HTT和Socket之间、长连接和短连接的区别?

1、前言

不过由于基于HTTP直接创建的长连接是无状态的,所以还是没办法直接通过HTTP监听连接状态。
这时候就需要实现一个插件,用于控制HTTP和TCP协议直接的通讯状态,而这个插件就是Scoket。

2、什么是Scoket?

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。
在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议组隐藏在Socket接口后面,
对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
如下图:
image.png
通信过程:
image.png
主机 A 的应用程序要能和主机 B 的应用程序通信,必须通过 Socket 建立连接,
而建立 Socket 连接必须需要通过底层 TCP/IP 协议来建立 TCP 连接。
建立 TCP 连接需要通过底层 IP 协议来寻址网络中的主机。
我们知道网络层使用的 IP 协议可以帮助我们根据 IP 地址来找到目标主机,但是一台主机上可能运行着多个应用程序,
如何才能与指定的应用程序通信就要通过 TCP 或 UDP 的地址也就是端口号来指定。
这样就可以通过一个 Socket 实例唯一代表一个主机上的一个应用程序的通信链路了。

3、如何建立通信链路?

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

4、什么是异步、同步?

同步:
很简单,我们在运行一段PHP代码的时候,是不是要等代码从上到下执行完成,页面才会显示出结果。
Socket也是一样,当一个TCP连接没有响应出结果之前,死等结果,不会去处理下一个请求。
这时候client 和 server双方都必须要保持页面连接,否则将无法接收到响应结果。
异步:
当一个请求处理时间太长时,client不可能一直在等待server处理完成,才去做其他的事情,
而是会关闭浏览器页面,去做其他的操作,例如淘宝下单后,可以退出页面,商家发货成功后页面会直接弹出消息,告知你已发货。
这就是异步处理。
client 和 server双方无需一直保持页面连接,只需要TCP连接在保活的状态下,就能对其进行消息推送。

5、什么是堵塞、非堵塞?

阻塞:
阻塞调用是指调用结果返回之前,当前线程会被挂起
(线程进入非可执行状态,在这个状态下,cpu不会给线程分配时间片,即线程暂停运行)。
函数只有在得到结果之后才会返回。
有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。
对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。
例如,我们在socket中调用recv函数,如果缓冲区中没有数据,这个函数就会一直等待,直到有数据才返回。
而此时,当前线程还会继续处理各种各样的消息。
非阻塞:
非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。
对象的阻塞模式和阻塞函数调用
对象是否处于阻塞模式和函数是不是阻塞调用有很强的相关性,但是并不是一一对应的。
阻塞对象上可以有非阻塞的调用方式,我们可以通过一定的API去轮询状态,在适当的时候调用阻塞函数,就可以避免阻塞。
而对于非阻塞对象,调用特殊的函数也可以进入阻塞调用。
函数select就是这样的一个例子。
同步异步 与 堵塞非堵塞的区别:
1. 同步,就是我调用一个功能,该功能没有结束前,我死等结果。
2. 异步,就是我调用一个功能,不需要知道该功能结果,该功能有结果后通知我(回调通知)。
3. 阻塞, 就是调用我(函数),我(函数)没有接收完数据或者没有得到结果之前,我不会返回。
4. 非阻塞, 就是调用我(函数),我(函数)立即返回,通过select通知调用者。

6、注意事项

Windows操作系统下对Socket的支持并不友好,所以在尽可能的情况下不要在Windows操作系统中搭建Socket连接业务。
如果硬要在Windows操作系统中使用Socket,可以通过修改下列参数,来提高连接性能(转载自网络):
可以通过调整系统参数来控制单机的最大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建立的速度。