AWS SQS异步客户端连接获取超配置最大时长异常求助
问题根因与解决方案
你遇到的连接获取超时问题,主要由以下2个常见的易忽略错误导致,按优先级排查解决即可:
1. 修复SqsSourceSettings无效配置的bug
Alpakka SQS的SqsSourceSettings是不可变类,所有with前缀的配置方法都会返回全新的配置实例,你现有代码中调用配置方法后没有重新赋值给变量,相当于你设置的maxBatchSize、maxBufferSize、waitTime完全没有生效,程序运行时用的是默认参数,很容易出现请求速率和连接池配置不匹配的问题。
修改后的配置代码如下:
private static SqsSourceSettings getSqsSourceSettings(final Config configuration) { SqsSourceSettings sqsSourceSettings = SqsSourceSettings.create().withCloseOnEmptyReceive(false); if (configuration.hasPath(ConfigPaths.SqsSource.MAX_BATCH_SIZE)) { // 接收with方法返回的新实例 sqsSourceSettings = sqsSourceSettings.withMaxBatchSize(10); } if (configuration.hasPath(ConfigPaths.SqsSource.MAX_BUFFER_SIZE)) { sqsSourceSettings = sqsSourceSettings.withMaxBufferSize(1000); } if (configuration.hasPath(ConfigPaths.SqsSource.WAIT_TIME_SECS)) { sqsSourceSettings = sqsSourceSettings.withWaitTime(Duration.of(20, SECONDS)); } return sqsSourceSettings; }
2. 调整连接池配置适配长轮询和业务操作
你使用了20秒的SQS长轮询,每个拉取消息的请求会最多持有连接20秒才返回,现有配置的maxConcurrency=100的连接会被拉取请求完全占满,如果你消费完消息后调用deleteMessage/changeMessageVisibility等操作复用的是同一个SqsAsyncClient,这些操作根本拿不到空闲连接,就会抛出连接获取超时异常,按如下规则调整即可:
- 提高
NettyNioAsyncHttpClient的maxConcurrency到200~300,预留足够的空闲连接给删除消息等管理类操作,不要全被长轮询拉取请求占用 - 把
connectionMaxIdleTime调整为25~30秒,长于20秒的长轮询时间,避免长轮询请求还没返回,连接就被空闲回收,反而需要频繁创建新连接消耗资源 - 可根据业务接受度适当缩短长轮询时间到10~15秒,加快连接释放的速度,降低连接池占满的概率
3. 可选优化
如果调整后还有偶发异常,可以把拉取消息用的SqsAsyncClient和删除消息用的SqsAsyncClient拆分为两个独立的实例,完全隔离两类操作的连接池,从根源上避免资源竞争。
内容的提问来源于stack exchange,提问作者Freid001
相关产品推荐
相关产品推荐

