使用具有消息组 ID 的 FIFO AWS SQS 连接多个生产者和多个使用者



>假设我们有一个 AWS FIFO SQS 队列和两个消息生产者 A 和 B。每条消息都使用等于生产者名称的组 ID 发送。换句话说,生产者 A 将组 ID "A"添加到每条消息,生产者 B 将组 ID "B"添加到每条消息。我们还有 3 个使用者 X、Y 和 Z 使用具有可见性超时的消息。假设队列中有 5 条消息 — 三条消息来自生产者 A,两条消息来自生产者 B。见下图

考虑到给定的条件,我们将有以下工作流程:

其中一个使用者(例如 X(从队列中接收组 ID 为 B 的消息 1,这使得此消息和具有组 B 的所有其他消息不可见,直到消息 1 被处理并从队列中删除。

然后,另一个使用者(例如 Y(收到组 ID 为 A 的消息 2,这使得消息 2 和所有其他具有组 A 的消息不可见,直到消息 2 被处理并从队列中删除。

现在,消费者 Z 无法使用任何消息,因为组 A 被已处理的消息 2 阻止,组 B 被已处理的消息 1 阻止。

是否有一种技术允许使用者 Z 在给定情况下使用队列中的下一条消息?

更新 1:为什么我使用 FIFO 队列和组 ID?

假设生产者 A 和 B 代表两个用户,并且使用简单队列而不是 FIFO。也没有附加到消息的组 ID。

考虑这样一种情况:生产者 A 向队列发送一百条消息,紧接着,生产者 B 也只向队列发送一条消息。生产者 B 的这条消息必须等到 A 的所有消息都处理完毕,这不好。我们需要在 A 和 B 的消息之间进行负载平衡,尽管 A 有一百条消息而 B 只有一个消息。

为此,让我们尝试添加组 ID,并且由于只有 FIFO 队列支持它们,因此我们必须将简单队列替换为 FIFO。现在上面的问题解决了。当任何生产者的 A 消息正在传输时,其中一个使用者将收到生产者 B 的消息,即使此消息位于队列的后面。我们现在在 A 和 B 之间进行负载平衡。

然而,当所有组都有正在传输的消息时,就会出现问题(在这种情况下,队列看起来是空的(,但我们目前有更多的可用消费者无法工作,这也不太好。

更新2:建议的解决方案。

每个生产者有多个组 ID

假设我们有 10 个使用者,只有一个生产者 A.让我们将 1 到 10 的数字添加到每个消息组 ID 加上一些表示批处理的唯一 ID(如果有 10 条消息(,因此我们将有组 ID "A1-batch1"、"A2-batch1"、"A3-batch1",依此类推,直到"A10-batch1"。如果生产者 A 有更多消息,我们增加批号并为另外 10 个生成组 ID,然后再生成另外 10 个。现在每个消费者都保证收到一条消息,这很棒。但是,如果生产者 B 现在发送一条消息,那么在最坏的情况下,生产者 A 和 B 之间的平衡比率将是 10 比 1,这不是很好。此外,消费者是水平可扩展的,因此生产者必须知道当前的消费者大致数量。

每个生产者的单独队列

生产者是当前使用该服务的用户。当用户连接到服务并通知使用者有关添加的队列时,我们必须创建简单队列。使用者必须连续拉取每个当前存在的队列,并且即使有正在传输的消息,也应该能够接收新消息。在这种情况下,负载平衡是可以的。此解决方案增加了体系结构的复杂性,但应该有效。除非我错过了一些技术限制。

队列将按照您的描述进行操作,这是有意为之

只有两个不同的组 ID。如果两个组 ID 都在传输中,则无法检索其他消息。

如果这给您带来了问题,那么您很可能错误地使用了组 ID。

组 ID 基本上是"请按顺序处理这组消息"。因此,如果一条消息仍在处理中,SQS FIFO 队列会阻止检索和处理来自同一组 ID 的另一条消息。您想获取另一条具有相同组 ID 的邮件这一事实向我表明,您不希望按顺序处理该组邮件,因此您应该使用不同的组 ID

通过使用链接到生产者的组 ID,并且只有两个生产者,您将只有两个使用者处理队列。

最新更新