Amazon SNS FIFO-先进先出发布/订阅消息

2020-10-24 20:47:32

在设计分布式软件体系结构时,定义服务如何交换信息非常重要。例如,异步通信的使用将组件解耦并简化了扩展,从而降低了更改的影响,并使发布新功能变得更容易。

两种最常见的异步服务到服务通信形式是消息队列和发布/订阅消息传递:

使用消息队列,消息将存储在队列中,直到使用者处理和删除它们。在AWS上,Amazon Simple Queue Service(SQS)提供完全托管的消息队列服务,几乎没有管理开销。

通过发布/订阅消息,发布到主题的消息将传递给该主题的所有订阅者。在AWS上,Amazon Simple Notification Service(SNS)是一种完全托管的发布/订阅消息传递服务,可将消息传递给大量订阅者。每个订阅者还可以设置过滤策略,以仅接收其关心的消息。

当您想要将邮件散布到多个应用程序时,可以使用主题;当您想要将邮件发送到一个应用程序时,可以使用队列。将主题和队列一起使用,可以将微服务、分布式系统和无服务器应用程序解耦。

使用SQS,您可以使用先进先出(FIFO)队列来保持邮件发送和接收的顺序,并避免多次处理一封邮件。

介绍SNS FIFO主题今天,我们通过引入SNS FIFO主题,为发布/订阅消息传递添加了类似的功能,为一个或多个订阅者提供严格的消息排序和经过重复数据消除的消息传递。

排序-在将消息发布到FIFO主题时,您可以通过包含消息组ID来配置消息组。对于每个消息组ID,所有消息都按照它们到达的顺序发送和传递。例如,为了保证与同一客户相关的消息按顺序投递,您可以使用客户的账号作为消息组ID将这些消息发布到主题,具有FIFO主题和队列的消息组数量没有限制。您不需要事先声明消息组ID,任何值都可以。如果您在消息之间没有逻辑区别,您可以简单地对所有消息使用相同的消息组ID,并拥有单个有序消息组。消息组ID被传递到任何订阅的FIFO队列。

重复数据消除-分布式系统(如SNS)和客户端应用程序有时会生成重复消息。您可以通过两种方式避免主题中的重复邮件传递:一种是在主题上启用基于内容的重复数据删除,另一种是向发布的邮件添加重复数据消除ID。对于基于邮件内容的重复数据删除,SNS使用SHA-256散列来使用邮件正文生成邮件重复数据消除ID。具有特定重复数据消除ID的邮件成功发布后,有5分钟的间隔,在此期间,任何具有相同重复数据消除ID的邮件都会被接受,但不会被传递。如果您为FIFO队列订阅FIFO主题,则重复数据消除ID将传递给队列,SQS使用它来避免接收重复消息。

您可以将FIFO主题和队列一起使用,以简化操作和事件顺序非常关键的应用程序的实现,或者在您不能容忍重复的情况下使用FIFO主题和队列。例如,处理财务操作和库存更新,或异步应用从客户端设备接收的命令。FIFO队列可以在FIFO主题中使用消息筛选,有选择地只接收消息子集,而不是发布到主题的每条消息。

如何使用SNS FIFO主题FIFO主题可以提供帮助的常见情况是当您收到需要按顺序处理的更新时。例如,我可以使用FIFO主题从我的客户编辑其帐户配置文件的应用程序接收更新。然后,我为FIFO主题订阅了一个SQS FIFO队列,并将该队列用作Lambda函数的触发器,该函数将帐户更新应用于我的客户管理系统使用的Amazon DynamoDB表,该表需要保持同步。

FIFO主题引入的解耦使添加新功能变得更容易,而对现有应用程序的影响最小。例如,为了用额外的促销来奖励我的忠实客户,我添加了一个新的忠诚度应用程序,该应用程序将信息存储在由Amazon Aurora管理的关系数据库中。要使存储在忠诚度数据库中的客户信息与我的其他应用程序保持同步,我可以向相同的FIFO主题订阅一个新的FIFO队列,并添加一个新的Lambda函数,该函数以生成客户更新的相同顺序接收客户更新,并将它们应用到忠诚度数据库。这样,我就不需要更改其他应用程序的代码和配置来集成新的忠诚应用程序。

首先,我在SQS控制台中创建了两个FIFO队列,将所有选项保留为默认值:

Loyalty.Fipo队列帮助我收集和存储忠诚度应用程序的客户更新。

在SNS控制台中,我创建了Dupdates.Fio主题。我选择FIFO作为类型,并启用基于内容的邮件重复数据删除。

为了能够接收消息,我在两个队列的访问策略中添加了一条语句,授予updates.Fio主题向队列发送消息的权限。例如,对于customer.fio队列,语句为:

{ ";效果";:";允许";, ";主体";:{ ";服务";:";sns.amazonaws.com"; }, ";操作";:";SQS:SendMessage";, ";资源";:";arn:aws:sqs:us-east-2:123412341234:customer.fifo";, ";条件";:{ ";ArnLike";:{ Aws:SourceArn";:";arn:aws:sns:us-east-2:123412341234:updates.fifo"; } } }。

现在,我使用SNS控制台按顺序发布4条消息。对于所有消息,我都使用相同的消息组ID。这样,它们都在同一个消息组中。唯一不同的部分是消息正文,我在其中按顺序使用:

在SQS控制台中,我看到只有3条消息传递到FIFO队列:

为什么会这样呢?创建FIFO主题时,我启用了基于内容的重复数据删除。这4封邮件是在5分钟重复数据消除窗口内发送的。最后一条消息已被识别为第一条消息的副本,并且尚未传递到订阅队列。

让我们看看队列中的实际消息。我使用AWS命令行界面(CLI)从SQS接收消息,使用JQ命令行JSON处理器格式化输出并仅获取正文中的消息。

$AWSSQS接收消息--队列-url https://sqs.us-east-2.amazonaws.com/123412341234/customer.fifo--最大消息数10|jq;.Messages[].Body|Fromjson|.Message&39; ";更新一个"; ";更新两个"; ";更新三";

$AWSSQS接收消息--队列-url https://sqs.us-east-2.amazonaws.com/123412341234/loyalty.fifo--最大消息数10|jq;.Messages[].Body|Fromjson|.Message&39; ";更新一个"; ";更新两个"; ";更新三";

不出所料,具有独特内容的3条消息已按照与发送顺序相同的顺序传送到两个队列。

现已提供,您可以在所有商业区域使用SNS FIFO主题服务。每个FIFO主题或FIFO队列最高每秒可处理300笔交易(TPS)。使用SNS,您只需为使用的内容付费,您可以在服务定价页面中找到更多信息。