Java HttpClient 连接池复用分析

Java HttpClient 连接池复用分析

在Java 11中,HttpClient被添加进去。支持Http/1.1 和Http/2,并分别支持同步和异步调用两种方法。
上周使用HttpClient, 对一个后端服务进行压测,遇到了一些问题。

场景描述

场景比较简单,就是开200个线程,对后端服务接口进行压测,服务接口调用使用Java HttpClient。
在这里插入图片描述

问题描述

从后端服务监控看,RPS远不及预期,从LB的监控看,有数4000+的并发连接。这和实际的情况不符啊。
我开了200个线程,HttpClient的调用采用同步方式调用,按道理使用连接池,应该是200个并发链接才对,这里面一定有问题。
在这里插入图片描述

日志分析

先看下客户端日志吧,有大量的日志如下,
在这里插入图片描述

应该是创建的连接过多,创建新的tcp连接失败,再使用netstat 看下tcp连接的情况,
在这里插入图片描述
很快就达到16000多个连接。这说明连接池肯定没有复用。

有两种可能,一种是用完的连接没有回收到连接池,一种是请求的时候没有从连接池中获取到可复用的连接。

代码分析

单步调试下,在
HttpConnection::getConnection()中,

   if (!secure) {
        c = pool.getConnection(false, addr, proxy);
        if (c != null && c.checkOpen() /* may have been eof/closed when in the pool */) {
            final HttpConnection conn = c;
            if (DEBUG_LOGGER.on())
                DEBUG_LOGGER.log(conn.getConnectionFlow()
                                 + ": plain connection retrieved from HTTP/1.1 pool");
            return c;
        } else {
            return getPlainConnection(addr, proxy, request, client);
        }
    } else {  // secure
        if (version != HTTP_2) { // only HTTP/1.1 connections are in the pool
            c = pool.getConnection(true, addr, proxy);
        }
        if (c != null && c.isOpen()) {
            final HttpConnection conn = c;
            if (DEBUG_LOGGER.on())
                DEBUG_LOGGER.log(conn.getConnectionFlow()
                                 + ": SSL connection retrieved from HTTP/1.1 pool");
            return c;
        } else {
            String[] alpn = null;
            if (version == HTTP_2 && hasRequiredHTTP2TLSVersion(client)) {
                alpn = new String[] { "h2", "http/1.1" };
            }
            return getSSLConnection(addr, proxy, alpn, request, client); // 跑到这了
        }
    }

跑到了最后,协议走的是http/2。 协议如果走的http/2的话,没有从连接池中获取可复用连接。

解决

那么,显示的指定下http协议版本1.1。
重新跑下,
在这里插入图片描述
可以看到连接数变成了200个,也不再报错了,并发请求量也提升了。

总结

  • 一定要显示的声明协议版本,否则缺省是http/2(支持ssl情况下);
  • 如果是http/2,不会使用连接池,导致创建过多的连接,有可能将客户端和服务器都打死。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值