前段时间AWS推出了SQS FIFO queue ,它保证消息排序
和精确的一次处理
。
我的问题是关于第二个假设,是否应该将其更改为恰好一次交付
?
因为即使队列中只能传输消息的一份副本,我也可以考虑可以多次处理消息的情况。 一个例子可能是:
- Worker1 从队列中轮询消息。可见性超时开始。
- 由于流量/负载较高,worker1 超出了可见性窗口来处理消息。
- 消息返回在队列中可见。
- Worker2 从队列中轮询相同的消息。
- Worker1 结束处理消息。
- Worker2 结束处理消息。
据我所知,即使使用 FIFO 队列,我们仍然需要幂等工作线程。 我的假设正确还是我遗漏了什么?
最佳答案
My question is about the second assumption, shouldn't it be changed to exactly one
delivery
?
不,因为消息实际上可以多次传递给消费者。 仅一次处理是更合适的命名约定,因为从队列中确认/删除消息是“处理”消息的一部分。
这与标准队列相反,在标准队列中,一条消息可以多次出现在队列中,例如,由于消息生产者中的重试。文档的“FIFO 传送逻辑”部分更详细地介绍了这一点。
we still need to have idempotent workers even when using FIFO queues
是的,没错。无论您是否使用 FIFO 队列,幂等性仍然是您的应用程序的一个重要考虑因素;你不能仅仅因为使用了 FIFO 队列就忽略它。由于对“处理”含义的不同解释,这可能会产生误导。队列无法判断与消息相关的工作是否真正执行——系统只关心消息是否被删除,因为如果消息没有被删除,则需要再次传递消息。
还要考虑到消费者完全有可能在实际执行工作之前或之后确认消息。
为了说明这两点,以基本队列使用者工作流程为例:
- 工作人员(消费者)从队列中获取消息。这里,可见性超时开始。
- 工作人员根据消息执行某些任务(例如,尝试银行交易)
- 执行任务后,工作人员会删除该消息,将其从队列中移除。
现在,假设工作系统在步骤 1 和步骤 3 之间某个时候遇到突然故障。工作可能(也可能没有!)已完成,但消息不会被删除。一旦可见性超时到期,该消息将可见并可供其他工作人员拾取。
因此,工作人员有必要能够确定系统的真实状态。例如与该消息相关的事务是否已经执行。
关于 FIFO 队列如何防止重复数据删除,您在设计系统时必须考虑许多其他注意事项。
关于amazon-web-services - AWS SQS FIFO队列仍然要求消费者是幂等的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60719041/