如何确保将消息放入消息队列?

时间:2021-06-28 12:40:15

标签: microservices message-queue messaging

我已经为消息传递设置了一个 RabbitMQ,集成工作正常。我正在将消息发送到队列并从队列中使用。但是我如何确定在执行任务后向队列发送消息?

例如,当我向DataBase添加一个新项目后,我应该向队列发布一条消息。

DBContext.SaveChanges(item);

//what if an error occurred at this moment.
QueueManager.Publish(item)

这种情况下的最佳做法是什么?任何建议将不胜感激。

我阅读了此解决方案 Solution

但我认为应该有更好的解决方案,因为这种方法有两个问题:

  1. 在微服务架构中,可能有些数据库不支持原子事务
  2. 它需要额外的数据操作和额外的后台服务来从数据库中删除记录

4 个答案:

答案 0 :(得分:2)

<块引用>

我怎样才能确定发送消息到队列之后 执行任务?

创建新的表名Event,使用包含NonPublished事件记录的Event表。完成数据库调用后,在事件表中创建一个条目并将该事件标记为未发布。将事件发布到队列后,将该记录更新为已发布事件。

如果应用程序无法发布事件(队列系统关闭,发布者失败)会怎样?

编写一个定期运行的后台作业/cron 作业,它将检查所有未发布事件并发布到队列并使状态为已发布。还要配置重试机制,如 Tarun 提到的如果发布的事件失败。

有关事件驱动微服务的更多信息,请参阅以下链接。

https://www.nginx.com/blog/event-driven-data-management-microservices/

答案 1 :(得分:1)

<块引用>

微服务架构中可能有些数据库不支持原子事务

我认为,如果您处于发布可能失败的位置,并且功能至关重要,那么原子事务支持就不能是可选的。所以,你尝试发布,如果失败,回滚事务。这意味着在解决方案 Best way to ensure an event is eventually published to a message queuing sytem 中,我什至不喜欢使用异步发布。

如果该功能那么重要,那么您可以进行各种优化,包括将错误消息放入日志中,以防它偶尔发布失败。< /p> <块引用>

它需要额外的数据操作和额外的后台服务来从数据库中删除记录

通常,用户更喜欢安全而不是抱歉的方法。因此,当功能不重要时,这应该没问题。

谢谢, -尼尔。

答案 2 :(得分:0)

您可以使用微服务弹性模式中的重试模式。

<块引用>

Retry – 源应用程序可以立即重试向服务发送请求。如果特定故障异常或罕见,则重复请求时成功的概率非常高。

<块引用>

延迟后重试 - 源应用程序可以在一段时间(通常呈指数增长)后重试将请求发送到云服务。这是由于云服务繁忙等原因导致故障事件的常见做法。 如果故障是由更常见的连接或繁忙故障之一引起的,则应用程序必须等待一段时间并重试.

来源:Retry Pattern

答案 3 :(得分:0)

我不知道我是否误解了您的问题或其他回答您问题的人是否有误解,但据我所知,如果 SaveChanges() 成功完成,您想向队列发布消息吗?通常,该方法应返回一个布尔值或您正在保存的对象,因此如果返回 true/您可以发送消息的对象。

像这样:

if(DBContext.SaveChanges(item)) {
QueueManager.Publish(item)
} else {
// Error handling

}

相关问题