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_encoding
为chunked
传输,则表示body是流式输出,body会被分成多个块,每块的开始会标识出当前块的长度,此时,body就不需要长度了。如果是非流式输出,而且有content_length
,则按其来接收出具。如果这两个都没有,则是服务器端主动断开。
打开长连接
当服务器端输出完body后,会考虑使用长连接。当然,能否使用长连接,也是有条件限制的。
如果客户端的请求头中的connection
为close
,则表示客户端需要关系长连接。如果为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开发从入门到精通