keepalive

作为一个web服务器架构,Nginx当然也支持长连接

http请求是基于TCP协议的。当客户端发起请求前,需要先与服务端建立TCP连接,而每一次TCP连接是需要三次握手来确定的。如果客户端与服务端之间通讯质量变差,那么这三次握手所带来的时间消耗就不可忽略了。
当连接断开后,也会有四次交互。当然,这并不会影响用户体验。

http呢,是请求应答式的。如果我们可以知道每个请求头和响应体的长度,那么我们就可以在一个连接上执行多个请求这也就是长连接

但这都是建立在我们知道请求请求头和响应体长度的。对于请求来说,如果当前请求需要有body,那么Nginx就需要客户端在请求头中指定content-length来表示body,如果没有,就返回400错误。

http对body长度的确定

  • 如果是http 1.0版本,如果响应头中有content-length头,则以其就可以知道body的长度。如果没有content-length,客户端就会一直接受数据,直到服务器端主动断开,才表示body接收完了。
  • 如果是http 1.1版本,如果响应头中的Transfer_encodingchunked传输,则表示body是流式输出,body会被分成多个块,每块的开始会标识出当前块的长度,此时,body就不需要长度了。如果是非流式输出,而且有content_length,则按其来接收出具。如果这两个都没有,则是服务器端主动断开。

打开长连接

当服务器端输出完body后,会考虑使用长连接。当然,能否使用长连接,也是有条件限制的。

如果客户端的请求头中的connectionclose,则表示客户端需要关系长连接。如果为keep-alive,则客户端需要打开长连接。

如果请求中没有connection这个头,那么根据协议,如果是http 1.0,则默认为close,如果是http 1.1,那么默认为keep-alive

如果结果为keep-alive,那么,Nginx在输出完响应体后,会设置当前连接的keep-alive属性,然后再次等到客户端的下一次请求数据。当然,如果客户端一直不发送数据,Nginx会设置超时时间,如果超时,则会关闭连接。

pipe

http 1.1中,引入了新特性,即pipeline

pipeline其实就是流水线作业,可以看做是长连接的一种升华,因为pipeline也是基于长连接的,其目的就在于利用一个连接作多次请求

对于之前的keep-alive来说,如果客户端要提交多个请求,那么第二个请求,必须要等到第一个请求的响应接收完全后,才能够发起。而对pipeline来说**,客户端不必等到第一个请求处理完后就可以发起第二个请求**。根据tcp全双工的特性,,我们可以在服务端依次处理,这样多个请求就是同时进行的。

lingering_close

字面意思就是延迟关闭。也就是说,当Nginx要关闭连接的时候,并非是立即关闭连接,而是再等待一段时间后才真正关掉连接。

参考文献

[1] Nginx开发从入门到精通