【问题标题】:Release a message back to AWS SQS with 20secs visibility time以 20 秒的可见时间向 AWS SQS 发布消息
【发布时间】:2020-08-06 06:28:31
【问题描述】:

我正在使用 spring-boot:2.2.6.RELEASEaws-java-sdk-sqs:1.11.415。我有一个从 SQS 轮询消息的侦听器。有一个条件是侦听器处理消息,如果不满足条件,那么我们应该将消息放回队列,并且在 20 秒后它应该可供任何其他组件或同一个侦听器使用。我不知道如何实现后一个,将消息放回队列,20秒后它应该对其他听众可见,

请参考以下代码,

@Autowired
private QueueMessagingTemplate messagingTemplate;

@PostMapping("/employee")
public String save(@RequestBody Employee employee){
    Map<String,Object> headers = new HashMap<>();
    headers.put("subject", "send employee details to sqs");
    headers.put("name","Donald");
    headers.put("traceId","sample");
    messagingTemplate.convertAndSend("sample-standard-queue", employee, headers);
    return "success";
}

@SqsListener(value = "sample-standard-queue")
public void receivesqs(Employee message, @Headers Map<String,Object> headers, @Header("name") String name) {

    // Retrieve employee details from DB using message.id
    // If it is in-progress then place the message back to the queue and it should be visible after 20secs
}

我看到了这个post 但是它将消息放回队列中,其他读者可以立即使用它。在我的情况下,它应该在 20 秒后可用。

【问题讨论】:

  • 一般来说,将消息放回队列并不是一个好主意。如果工作人员处理消息失败,则在 Invisibility Period 到期后,该消息将自动放回队列中。
  • @JohnRotenstein 我知道如果工作人员无法处理消息,那么它将自动放回队列中。但是什么时候可以提供给其他读者呢?我的用例是它应该仅在 20 分钟后可供相同或其他读者使用
  • 从队列中检索消息后,它将在不可见期中指定的持续时间内保持不可见。队列有一个默认的不可见期,但也可以在检索消息时指定。取回消息的进程也可以change_message_visibility()增加超时时间。如果消息在不可见期间没有被删除,它将重新出现在队列中。因此,请将您的隐身时间设置为最多 20 分钟。
  • @JohnRotenstein 默认隐身时间为 30 秒。因此,如果我将其更改为 20 秒,那么我相信其他消费者将在 20 秒内再次看到它。另一个消费者或阅读者应该在 20 秒内完成对消息的处理,因为我们将其更改为 20 秒,否则消息将被重复。我说的对吗?
  • 是的。消息不会被复制。它只会重新出现在队列中以供其他工作人员使用。

标签: java spring spring-boot aws-sdk amazon-sqs


【解决方案1】:

这里提到SQS Listener Manual Acknowledgement

@SqsListener(value = "sample-standard-queue", deletionPolicy = SqsMessageDeletionPolicy.NEVER) 不会删除消息,您可以通过确认参数手动删除它们。

 @SqsListener(value = "sample-standard-queue", deletionPolicy = SqsMessageDeletionPolicy.NEVER)
    public void receivesqs(Employee message, @Headers Map<String,Object> headers, @Header("name") String name,Acknowledgment acknowledgment)  {
        // decide when to acknowledge
        acknowledgment.acknowledge().get();
    }

根据您的可见性超时设置,消息将在可见性超时秒后重新出现在队列中。

【讨论】:

  • 如何根据确认参数删除消息?
  • @VelNaga 如果您不确认,则默认情况下不确认。
猜你喜欢
  • 1970-01-01
  • 2013-01-02
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多