当前位置: 首页 > 知识库问答 >
问题:

将消息推送到SQS时提供请求超时

壤驷阳冰
2023-03-14

我在我的项目中使用了SQS。我想在将消息推送到SQS标准队列时提供超时。我所说的超时(不是可见性超时)是指,如果我的消息没有在200毫秒内推送到SQS,那么我会在某个时候重试推送它。我使用JAVA API来实现同样的目的。

最初,我试图通过请求一个可调用的任务将消息推送到SQS来处理超时,它返回给我一个未来的对象,我通过提供超时来等待。但这导致请求被发送到SQS,当消息被推送时,我的超时出现在图片中,在收到这个已经推送的消息的响应之前,我的代码认为这是一个超时,因为这个未来的对象。

当我转到SQS的留档时,我找不到任何与在调用SQS推、拉或删除时提供请求超时相关的内容。

final Future<ISendMessageResult> future = timeoutHelperThreadPool.getExecutor().submit(() -> {
  return getQueueStore().sendMessage(request).get();
});
try {
  sendMessageResult = future.get(200, TimeUnit.MILLISECONDS);
  logger.info("SQS_PUSH_SUCCESSFUL");
  return true;

} catch (final TimeoutException e) {
  logger.error("SQS_PUSH_TIMEOUT_EXCEPTION");
}

是否有无论如何我可以确保,如果我收到了超时,我的消息不会被推送到SQS或反之亦然?

共有2个答案

陆俊智
2023-03-14

我建议您要么解决了错误的问题,要么试图解决一个基本上不可能解决的问题,这可能是因为您不了解向SQS推送消息时发生的底层操作的复杂性。

所有这些动作都需要非零的时间,而且在某种程度上,它们都是可变的。。。

SQS请求被转换为HTTP请求。

请求已签名。

如果没有发生故障,那么继续进行到这一点,您就可以有效地promise发送消息。

对于每条消息,接下来的三个步骤可能需要,也可能不需要。这取决于您最近是否已经与该服务进行了交互,这可能意味着您有一个缓存的DNS响应,或者甚至有一个与TLS建立的可重用TCP连接,在HTTP中保持活动状态,等待下一个请求,但这是一个通配符。

DNS查询查找SQS终结点。

建立到endpoint的传输控制协议。

建立TLS(SSL)会话。

HTTP请求通过线路发送。

此时,您仍在等待,时钟仍在滴答作响,但现在您无法阻止请求被处理,而且还有很多工作要做。关闭连接可能会导致服务停止处理请求,但没有理由期望它会停止,因为在尝试写入响应之前,服务不太可能看到连接已关闭。。。在这一点上,这是无关紧要的。

HTTP请求在线路上接收。(此项与前一项分开列出,因为在线路上传输请求也需要非零时间。)

服务会检查请求是否过期。

该服务检查请求是否正确签名。

该服务检查签名用户是否有权执行请求的操作。

服务实际处理请求的操作。

该服务生成一个响应。

响应通过电线发送。

通过电线接收到响应。

响应由客户端解析。

与任何web服务一样,一旦请求到达目的地,事情就失去了控制

tl; dr:面对超时,不可能保证消息没有发送。

另见两位将军的问题。

然而,这是SQS FIFO队列解决的问题之一。FIFO队列支持将消息重复数据消除ID(由您)分配给每条消息,这允许您在最长5分钟内安全地重试向SQS发送消息。在此时间窗口期间,如果您确实向同一队列发送了相同的消息(可能是由于超时引起的歧义),服务会丢弃重复的消息,但响应会告诉您传递成功,因为它确实。。。早期的。

邮件重复删除ID是用于删除已发送邮件的标记。如果成功发送了具有特定邮件重复删除ID的邮件,则使用相同邮件重复删除ID发送的任何邮件都将被成功接受,但在5分钟的重复删除间隔内不会传递。

https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagededuplicationid-property.html

谷善
2023-03-14

在里面你可以尝试抓块

catch (final TimeoutException e) {
  future.cancel(true);
  logger.error("SQS_PUSH_TIMEOUT_EXCEPTION");
}

这里需要注意的一点是,如果在线程被中断时消息已经发布到SQS,那么您将得到假阴性。我建议你为超时设置一些慷慨的值

 类似资料:
  • 我试图写一个请求从我的服务器获取消息在使用签名,消息看起来像这样, POST/134148934511/Localhost/?Action=ReceiveMessage 但我收到了一条错误消息(尽管我拥有所需的权限)。(我确信aws版本4的签名过程是正确的(通过S3检查))我做错了什么?

  • 我想用亚马逊SNS向2000万台设备发送时间紧迫的移动推送通知。每个话题最多可以有10000个设备,我最多可以创建3000个话题。使用Amazon PHP SDK意味着每1秒发送2000个API调用--总共33分钟。这对时间紧迫的消息没有好处。 我已经创建了一个SQS队列并将其订阅到SNS主题。当我将推送消息发送到SQS队列时,它不会被传递--它仍然留在队列中。

  • 我试图创建一个API来记录SQS队列中的JSON请求主体。 我已经在FIFO和非FIFO布局的SQS中设置了一个基本队列。我每次都有同样的问题。SQS队列的策略如下: 我已经创建了一个策略,我将所有访问SQS的权限都赋予了写能力。我已经为API网关创建了一个角色,在其中我将前面提到的策略分配给。以下是我为该角色分配的策略: 有没有一个AWS大师可以指引我走向正确的方向? 为了澄清我的问题,它应该添

  • 我有一个连接到lambda的队列(fifo)。我想在lambda中向标准队列发送一条消息。但没有发送/接收任何消息。然而,如果我尝试从非SQS连接的lambda(通过AppSync)发送它,它会工作。 我查过: lambda有权发送SQS消息(您可以在那里看到) 由于我已成功地从另一个lambda(非SQS)向标准队列发送消息,因此正确配置了标准队列 SQS URL是否正确 控制台中不会显示任何错

  • 消息推送 PDF版下载 如流开放了消息发送接口,企业可以使用这些接口让企业应用与用户间进行双向通信。 推送消息 向成员推送消息 请求方式:POST(HTTPS) 请求地址:https://api.im.baidu.com/api/message/send?access_token=ACCESS_TOKEN 请求body:(每种类型的消息请求body不同,详见消息推送格式) 参数说明: 参数 类型

  • 1、离线消息 接口说明: 接口类型:回调型接口 接口作用:智齿将客服发送给用户的离线消息推送至企业预先配置好的回调地址上。 请求方法: POST 请求格式: { "type": 202, //消息类型,表示客服发送消息给客户 "partnerId": "", //企业自己的用户id "msgId": "" ,//消息id "content": "" ,//客