nginx中keepalive_timeout参数的说明

在http1.1中增加了长连接的特性,在创建连接之后,在设定的时间范围内,客户端可以复用连接进行数据传输。这样就减少了建立连接的时间,对于服务器而言,由于要保持长连接,负载和可用的连接必然会减少。我们用tcpdump工具来分析下这样的行为。

在nginx中,keepalive_timeout参数可以设置长连接时间。值为0说明关闭长连接,为了便于观察,设置了60s为长连接时间。

设置keepalive_timeout为60s

客户端立即关闭连接

在php中,使用curl发送请求,请求完成后,立即调用curl_close进行关闭。

10.10.56.63请求的客户机ip。重点关注下时间点和flags字段。flags字段说明:S (SYN), F (FIN), P (PUSH), R (RST), U (URG), W (ECN CWR), E (ECN-Echo) or ‘.’ (ACK), or ‘none’。

10.10.56.63首先发起请求握手连接。在13:34:27.474422时间点,由客户机10.10.56.63发起了FIN标记断开连接。然后服务器10.10.72.152进行应答(ACK),并且也发送了FIN标记,最后客户端应答。至此,断开四步骤完成,请求完成。

客户端不立即关闭连接

为了模拟此请求,我们在curl_close之前,调用了sleep(70),模拟客户端延时关闭连接。

客户机在13:22:39发起了请求,由于没有关闭连接,连接一直保持。在60s后,在13:23:39,服务器10.10.72.152主动发送了FIN。又过了10s,在13:23:49,客户机才发送FIN请求,至此,整个请求完成。

这里需要说明的是,在keepalive_timeout时间内,客户端一直没有请求,服务端才会主动断开。否则,服务器会重置等待时间。在上面的例子中,应该以 13:22:39.296408 这个时间点计算, 60s后,服务器断开连接。

浏览器发起请求

设置好host, 请求url为http://dingjing.operation.youku.com/queue/message/send.json?%20task_name=task_wq_test&message=%7B%22currtime%22%3A1446958970%7D&type=1&pub_key=T001&sign_type=MD5&sign=48710e1309f3b1cb1549b1248a752eaa

从浏览器发送请求时,请求头默认会有Connection:keep-alive。如果服务器开启了keep-alive,回复头里也会包含此值。上面的报文中,也是服务端超时60s后,主动断开连接。

关闭keepalive_timeout

如果服务端关闭了keep-alive。在上面的三种情况下,服务端回复完成后会立即发送FIN,主动断开连接。

在这种情况下如果客户端保存了curl连接,多次使用curl_exec发送请求时,每次请求也是以单独的连接存在的。

总结

通过用户访问的请求,合理的设置keep-alive。如果单一用户多次频繁请求,设置合理的keepalive_timeout,是可以提高性能的。如果服务被多方调用,为了保障服务质量,最好关闭keepalive。在开启的情况下,客户端有可能存在bug,没有主动断开连接,或者恶意请求,服务器会因连接数过多,造成服务不可用。

反过来讲,如果某些内部接口,开启了keepalive, 在后端脚本发起请求时,可以不立即调用curl_close,而重用curl,达到长连接效果,提高处理速度。

以上讨论都是http1.1的。如果使用的http1.0,不管设置keepalive_timeout与否,服务器端都会主动断开连接。

此条目发表在nginx分类目录,贴了标签。将固定链接加入收藏夹。

发表评论

邮箱地址不会被公开。