其实网上有大量讨论HTTP长连接的文章,而且Idle Timeout和KeepAlive Timeout都是HTTP协议上的事情,跟Vert.x本身没有太大关系,只不过最近在项目上遇到了一些问题,用到了Vert.x的HttpClient,就干脆总结一下,留给自己今后做参考。
在使用Vert.x的HttpClient的时候,可以使用HttpClientOptions
配置KeepAlive Timeout以及Idle Timeout的行为,本文将讨论在Vert.x HttpClient中Idle Timeout的设置、如何启用和禁用KeepAlive,以及如果启用KeepAlive,其超时设置(Timeout)对HTTP连接保活的影响。
需要注意的是,这是客户端的设置,服务端由于实现技术多样,这里不深入讨论,本文默认服务端已经开启了KeepAlive(事实上也是大多数HTTP服务器的默认行为)。
本文讨论的场景仅适用HTTP/1.1的情况,HTTP/1.0处理KeepAlive方式略有不同,HTTP/1.1默认支持KeepAlive,HTTP/1.0需要显式在header里加入Connection: keep-alive。
场景演练
这里我们设定多个场景来测试不同情况下,整个系统的行为表现是什么。
场景一:HttpClient禁用 KeepAlive
HttpClientOptions
里使用setKeepAlive(false)
来禁用KeepAlive:
final HttpClientOptions options = new HttpClientOptions() |
|
.setKeepAlive(false); |
此时,Vert.x Http Client会在请求头中加入connection: close
,表示在完成一次HTTP request/response的流程后,服务端需要主动发起关闭连接请求:
Wireshark抓包分析:
- Vert.x HttpClient使用60489端口与服务端建立连接(SYN),服务端以(SYN, ACK)数据包回应,同意建立连接
- Vert.x HttpClient向服务端发送HTTP请求,服务端处理请求并返回
- 由于Vert.x HttpClient在发出HTTP请求时,使用了
connection: close
,所以服务端主动发起(FIN, ACK)数据包,表示服务端已关闭连接,客户端获得数据包后,返回ACK表示确认,然后也向服务端发出(FIN, ACK),表示客户端也关闭了连接,最后服务端返回ACK,表示确认