使用LambdaClient时抛出Connection pool shut down异常的原因排查
关于AWS LambdaClient抛出
Connection pool shut down异常的排查与解决 问题背景
每次调用Lambda时都会创建新的LambdaClient(因配置可能动态变化),且使用try-with-resources语句确保客户端自动调用.close()方法。但在随机次数的调用后,程序开始抛出Connection pool shut down异常,后续所有调用均失败,仅重启服务可恢复,且该异常未提供行号等详细信息。
相关代码
try (LambdaClient client = LambdaClient.builder() .region(region) .credentialsProvider(DefaultCredentialsProvider.create()) .overrideConfiguration( builder -> builder.apiCallTimeout(Duration.ofSeconds(118)) .apiCallAttemptTimeout(Duration.ofSeconds(118)) .retryPolicy(RetryPolicy.none())) .httpClientBuilder(ApacheHttpClient.builder() .maxConnections(10) .socketTimeout(Duration.ofSeconds(130)) .connectionTimeout(Duration.ofSeconds(130)) ) .build()) { res = client.invoke(request); lambdaResponse = res.payload().asUtf8String(); }
异常原因
- 全局HTTP连接池被共享并意外关闭:
ApacheHttpClient的默认实现中,底层连接池、线程池等资源是全局共享的,并非每个LambdaClient实例独立持有。当第一个LambdaClient被关闭时,会连带关闭全局共享的连接池,后续新创建的LambdaClient会复用已关闭的连接池,从而触发Connection pool shut down异常。 - 凭证提供者的全局资源冲突:
DefaultCredentialsProvider.create()创建的实例默认是全局单例,包含后台凭证刷新线程等资源。每次创建LambdaClient都调用该方法,会导致底层共享资源在某次客户端关闭时被终止,间接影响后续客户端的连接建立。
解决办法
- 优先复用LambdaClient实例:AWS SDK设计时就推荐将客户端作为长期对象复用,其内部已做线程安全处理。除非配置必须动态变更,否则不要每次调用都创建新客户端。
- 为每个客户端创建独立HTTP实例:如果必须每次创建新
LambdaClient,需显式构建独立的ApacheHttpClient实例,避免共享全局资源。修改代码如下:try (LambdaClient client = LambdaClient.builder() .region(region) .credentialsProvider(DefaultCredentialsProvider.create()) .overrideConfiguration( builder -> builder.apiCallTimeout(Duration.ofSeconds(118)) .apiCallAttemptTimeout(Duration.ofSeconds(118)) .retryPolicy(RetryPolicy.none())) .httpClient(ApacheHttpClient.builder() .maxConnections(10) .socketTimeout(Duration.ofSeconds(130)) .connectionTimeout(Duration.ofSeconds(130)) .build()) // 直接构建独立HTTP客户端,而非传入builder .build()) { res = client.invoke(request); lambdaResponse = res.payload().asUtf8String(); } - 统一管理凭证提供者:不要每次创建客户端都调用
DefaultCredentialsProvider.create(),复用同一个凭证提供者实例,或单独控制其生命周期,避免底层资源被意外终止。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

