当前位置: 首页 > article >正文

Connection lease request time out 问题分析

Connection lease request time out 问题分析

问题背景

使用apache的HttpClient,我们知道可以通过setConnectionRequestTimeout()配置从连接池获取链接的超时时间,而Connection lease request time out正是从连接池获取链接超时的报错,这通常意味着总连接池数不够,或者说单个rote的连接池太小。但本人在生产环境中这二者在当时都接口请求量都足够的情况下依旧出现了这个问题

可以看到总的连接池数是3800,单个路由是300,这在实际的环境运行中是完全足够的

@Bean(initMethod="start", destroyMethod = "close", name="httpAsyncNotifyClient")
public CloseableHttpAsyncClient httpAsyncNotifyClient(){
    RequestConfig config = RequestConfig.custom()
      .setConnectTimeout(NOTIFY_CONNECT_TIMEOUT)
      .setConnectionRequestTimeout(DEFAULT_REQUEST_TIMEOUT)
      .setSocketTimeout(NOTIFY_SOCKET_TIMEOUT)
      .build();
    CloseableHttpAsyncClient httpClient = HttpAsyncClients.custom()
      .setDefaultRequestConfig(config)
      .setMaxConnTotal(3800)
      .setMaxConnPerRoute(300)
      .setKeepAliveStrategy(getKeepAliveStrategy(true)).build();
    return httpClient;
}

但依旧出现了Connection lease request time out

在这里插入图片描述

问题分析

定位问题的来源是AbstractNIOConnPool#processPendingRequest()

private boolean processPendingRequest(final LeaseRequest<T, C, E> request) {
    final T route = request.getRoute();
    final Object state = request.getState();
    final long deadline = request.getDeadline();

    final long now = System.currentTimeMillis();
    if (now > deadline) {
        request.failed(new TimeoutException("Connection lease request time out"));
        return false;
    }
  	...
}

而这个方法在请求过程的调用着者是AbstractNIOConnPool#lease()我们注意到这里,这里使用了lock,而AbstractNIOConnPool是共用的连接池,也就是说如果有某个执行processPendingRequest()比较耗时,将会导致其他请求被锁在外面,最终导致获取链接超时

public Future<E> lease(
        final T route, final Object state,
        final long connectTimeout, final long leaseTimeout, final TimeUnit timeUnit,
        final FutureCallback<E> callback) {
    final LeaseRequest<T, C, E> leaseRequest = new LeaseRequest<T, C, E>(route, state,
            connectTimeout >= 0 ? timeUnit.toMillis(connectTimeout) : -1,
            leaseTimeout > 0 ? timeUnit.toMillis(leaseTimeout) : 0,
            future);
    this.lock.lock();
    try {
        final boolean completed = processPendingRequest(leaseRequest);
        if (!leaseRequest.isDone() && !completed) {
            this.leasingRequests.add(leaseRequest);
        }
        if (leaseRequest.isDone()) {
            this.completedRequests.add(leaseRequest);
        }
    } finally {
        this.lock.unlock();
    }
  	...
}

按理processPendingRequest()的理论上都是一些内部方法的调用,去检查是否有可以复用的链接、获取链接、去建立链接(异步的)等等按理不应该耗时,但其中有一个地址解析的方法,这里是做DNS的解析,通常情况下也是比较快的,但如果DNS服务有问题,的确有可能造成在这里耗时较长

remoteAddress = this.addressResolver.resolveRemoteAddress(route);

问题验证

这里使用asyncClient去提交两个请求,xxx.com这边找了一个DNS解析比较慢的域名(可以通过修改DNS解析服务器为国外的方式),第二请求则是一个比较快的域名

        RequestConfig config = RequestConfig.custom()
                .setConnectTimeout(2000)
                .setConnectionRequestTimeout(300)
                .setSocketTimeout(10 * 1000).build();
        CloseableHttpAsyncClient asyncClient = HttpAsyncClients.custom().setDefaultRequestConfig(config)
                .setMaxConnTotal(3800)
                .setMaxConnPerRoute(300)
                .build();
	...
executorService.submit(()->{
    asyncClient.execute(new HttpGet("https://xxx.com"), callback);
});

executorService.submit(()-> {
    asyncClient.execute(new HttpGet("https://www.baidu.com/"), callback);
});

结果

可以看到两个请求机会同时开始获取链接,但第二个请求却出现了Connection lease request time out异常

在这里插入图片描述


http://www.kler.cn/a/444017.html

相关文章:

  • 登山第十六梯:深度恢复——解决机器人近视问题
  • 解锁移动设备管理新技能-RayLink远程控制手机
  • 【Vue.js 3.0】provide 、inject 函数详解
  • Leetcode Hot 100 【二叉树】104. 二叉树的最大深度
  • UDP系统控制器_音量控制、电脑关机、文件打开、PPT演示、任务栏自动隐藏
  • Fastdfs V6.12.1集群部署(arm/x86均可用)
  • 基于java的CRM客户关系管理系统的设计与实现
  • 计算机必背单词——云计算和虚拟化
  • 数据结构:双向带头循环链表的增删查改
  • 使用Maven打包javaagent.jar
  • 关于解决VScode中python解释器中的库Not Found的问题
  • C# 开发应用篇——C# 基于WPF实现数据记录导出excel详解
  • Unity添加newtonsoft-json
  • 着色器 (三)
  • 游戏《姆吉拉的假面》启动时提示“xinput1_3.dll丢失”怎么办?“xinput1_3.dll丢失”要怎么解决?
  • 三、ubuntu18.04安装docker
  • 【openssl】 version `OPENSSL_3.0.3‘ not found 问题
  • conda-pack迁移虚拟环境
  • 【Qt】qt安装
  • 计算机网络知识点全梳理(三.TCP知识点总结)
  • xhr和Ajax
  • 免费获取宠物商城源码--SpringBoot+Vue宠物商城网站系统
  • apisix转发websocket
  • 【ArcGIS Pro】做个宽度渐变的河流符号
  • 如何使用arping命令检测IP地址冲突?
  • Windows部署Docker及PostgreSQL数据库相关操作