我有一个系统,客户机(我们称其为ClientA)可以将请求发布到特定的MQTT主题。代理(如果需要的话)是Amazon Web Services。然后,我有另一个客户端(我们称其为MainSubscriber),该客户端始终订阅相同的主题,以便它可以接收来自ClientA的请求并进行某些工作,最后将其转换为数据库操作。如果需要的话,该数据库是DynamoDB。由于MainSubscriber可能不总是可访问/在线的,因此希望有一个故障转移订阅服务器作为主订阅服务器的故障转移备份。这样的想法是,如果主用户未及时处理请求,则故障转移用户将加入并进行等效的工作/数据库操作。挑战在于,主订户和故障转移订户都不能复制“工作”和所产生的“数据库操作”。

这是该系统的逻辑系统架构图。

                   -----> MainSubscriber ----
                  /                          \
ClientA --> Broker                            ---> Database
                  \                          /
                   ---> FailoverSubscriber --


显然,这种系统存在一些挑战:


主订户如何向故障转移订户指示它正在使用请求?
故障转移订户如何检测到主订户尚未接听请求并需要开始处理请求?
故障转移订户如何在所有请求都被保留的情况下推迟主订户突然回到在线并接听请求?
如何处理主用户与故障转移用户之间的同步性问题?

如果现有的解决方案已经存在,我宁愿重新发明轮子对于这样的方案。因此,我的第一个问题是是否已经存在?

如果没有,那么我正在考虑使用具有强一致性读取的DynamoDB作为Main和Failover订户之间的中介。所以,我的第二个问题是,是否有完善的方案来做到这一点?

评论

您是否调查过像Amazon SQS这样的消息队列在这里是否有用?它似乎已经与AWS IoT集成在一起,并且看起来适合解决“工作队列”风格的问题。

#1 楼

根据AWS SQS文档(正如您所说的代理是AWS),这应该是本机的:


收到消息后,它立即保留在队列中。为了
防止其他使用者再次处理消息,Amazon SQS
设置了可见性超时,在这段时间内Amazon SQS
防止其他消耗组件接收和处理
消息。


问题是根据您的最大处理时间找到合适的可见性超时。在这种情况下,您的订户代码应尝试为数据库创建幂等输出(至少是相同的主键),并在尝试插入相同记录时应优雅地处理失败。

#2 楼

您可能想看看AWS SQS的死信队列的概念。从AWS文档中:


死信队列是其他(源)队列可以针对无法成功处理(消耗)的消息的队列。您可以
保留这些消息并将它们隔离在死信队列中,以
确定为什么它们的处理不成功。来从普通队列中侦听,从属订户从死信队列中侦听,则应该解决故障转移问题。

此外,还应注意1、2和3个问题的。在这种情况下,主要订户和次要订户不需要互相交谈。

此外,在Tensibai的回答基础上,请确保您的订户代码已编写,以便在出现以下情况时一次接收一条消息由于visibility timeout,多个订阅者正在侦听同一队列。缺点是,这将导致处理延迟,消息仅在一段时间后才进入死信队列。 >
所以,如果您不想这样做,那么可以继续进行Tensibai的回答。而且如果您可以忍受,那么可以使用它来代替进行状态检查的额外Dynamo表。