防止在松耦合系统中多次执行操作的策略(使用 Azure 服务总线和云工作者)

Strategies to prevent actions being carried out more than once in a loosely coupled system (using Azure Service Bus and Cloud Workers)

我正在开发一个使用 Push Sharp 发送多个推送通知的系统。

我当前的设计有两个服务总线队列和两个 Cloud Worker 角色。

当用户想要广播通知时,ASP.Net Web 应用程序将一条消息插入消息队列,由 Worker #1 读取。 Worker #1 确定通知所针对的设备(想想 1000s)。对于每个设备,Worker #1 将一条消息放入通知队列,这是使用批处理完成的,因此速度非常快。

Worker #2 读取通知队列中的消息并使用 Push Sharp 发送实际通知。

如果 Worker #2 出现问题,消息将被丢弃并最终重新处理,所以我很高兴这部分是可靠和持久的。

我担心的是 Worker #1。如果在将消息放入通知队列时失败,它将放弃该消息并重试。这可能会导致同一通知多次进入通知队列,从而导致人们在设备收到多个警报时感到恼火。

我正在考虑使用数据库来跟踪哪些通知已为哪个设备排队,因此 Worker #1 如果已经排队,则不会排队通知。这显然会给 Worker #1 添加一个瓶颈。理想的解决方案是将对通知队列的写入包装在一个事务中,但服务总线在单个事务中只允许 100 条消息。

我找到了很多关于使消息幂等的建议,但找不到将其应用到我的情况的方法。

我想确保无论发生什么情况,特定消息只发送到特定设备一次。欢迎任何建议或设计模式建议!

如果发件人可以始终如一地为消息生成相同的消息 ID,则服务总线为您提供一项功能:重复检测。

它由 RequiresDuplicateDetection flag and further controlled by DuplicateDetectionHistoryTimeWindow

启用

如果我们在给定时间内再次看到相同的 MessageId window,我们将丢弃第二条消息。