java.net.http.HttpClient 的连接复用、异步请求和 HTTP/2 到底怎么表现?这篇用自己起的 nginx(自签证书的 TLS + h2)与一个 JDK 自带的后端,用 nginx 日志里的连接编号数连接(HTTP/2 帧与多路复用在后面的篇目)。
客户端偏好 HTTP_2 → https 端口:response.version() = HTTP_2,状态 200,body = ok 客户端偏好 HTTP_2 → http 端口:response.version() = HTTP_1_1,状态 200,body = ok 客户端偏好 HTTP_1_1 → https 端口:response.version() = HTTP_1_1,状态 200,body = ok
同一个 HttpClient 顺序发 20 个请求(HTTP/1.1):53 ms 每个请求新建一个 HttpClient(HTTP/1.1):52 ms nginx 日志:shared 的 20 个请求用了 1 个连接;fresh 的 20 个请求用了 20 个连接
HTTP_2 并发 sendAsync 50 个各耗时 100 ms 的请求:总耗时 124 ms HTTP_1_1 并发 sendAsync 50 个各耗时 100 ms 的请求:总耗时 119 ms nginx 日志:HTTP/2 的 50 个请求用了 1 个连接(协议 ['HTTP/2.0']);HTTP/1.1 的 50 个请求用了 50 个连接(协议 ['HTTP/1.1'])
请求超时 500 ms 而服务端 3 秒才回:HttpTimeoutException: request timed out 连接一个没人监听的端口:ConnectException sendAsync 之后 200 ms 调用 future.cancel(true):返回 true,isCancelled = false,isDone = true,isCompletedExceptionally = true 之后 join() → CompletionException(cause = CancellationException)