给定具有以下代码的Java AWS Lambda:
private static final String QUEUE_URL = "https://sqs.us-east-1.amazonaws.com/<ACCT_NUMBER>/<QUEUE_NAME>";
private static final AmazonSQS client = AmazonSQSClientBuilder.standard().build();
private static final int MAX_SQS_MESSAGES = 10;
和:
private List<Message> getMessages() {
return client.receiveMessage(new ReceiveMessageRequest().withQueueUrl(QUEUE_URL)
.withMaxNumberOfMessages(MAX_SQS_MESSAGES).withWaitTimeSeconds(1)).getMessages();
}
作为日志的示例证据,我经历了相当长的SQS检索时间(考虑到为长时间轮询指定的1秒基准):
获得了3次SQS消息:1985ms
得到了8个SQS消息:1887ms
获得9 SQS消息:2438ms
获得5次SQS消息:1748ms
是在正常操作之间的时间间隔,还是我做错了什么或改善了什么?
Maven依赖项:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sqs</artifactId>
<version>1.11.488</version>
</dependency>
最佳答案
这些确实是很长的延迟,而且出了点问题。使用非空队列时,您应该能够获得5-500ms范围内的典型读取值(较低的值有更多消息可用)。即使您的队列为空,根据您在请求中使用withWaitTimeSeconds
的情况,请求时间也应该最多为1秒左右。
您可以采取许多步骤来缩小问题的范围:
确保队列和lambda在同一区域内-我首先提到这一点,因为我已经看到很多由AWS中跨区域调用引起的延迟问题。
确保您具有准确的请求指标。我看不到您如何在代码中衡量指标计时,但确实看到了您如何构建客户端。
创建实现RequestHandler2
和afterError
的afterResponse
实现,并检查request.getAWSRequestMetrics()
的详细信息
通过clientBuilder.withRequestHandlers(RequestHandler2... handlers)
将请求处理程序添加到客户端
这将为您提供有关请求如何花费时间的准确详细信息,并可能揭示一些明显的问题,还可能指向SQS调用之外的问题。
确保您正在重新使用客户端(而不是每次都创建一个新客户端)-请考虑在每次创建客户端时进行日志记录。在客户端的后台有很多设置,如果每次都使用一个新的客户端,那可能会浪费很多时间。
关于java - 从SQS检索消息缓慢,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54553772/