【问题标题】:Do I need transactional queues in Microservices?我需要微服务中的事务队列吗?
【发布时间】:2021-03-16 22:52:25
【问题描述】:

我正在学习微服务,我知道在我的场景中,我希望微服务使用消息队列相互通信,并具有持久性。这意味着如果实例崩溃并且消息没有被消费,它将在实例反弹(或者可能被另一个实例)时消费。

现在,既然这些消息很关键,它们不应该是事务性的并参与数据库事务吗?我看到使用 Kafka 或 RabbitMQ 的示例,但这些队列实现不实现事务。如果他们不这样做,很可能会丢失一些消息。

微服务真的需要事务吗?或者我应该以一种有弹性的方式设计我的微服务,以便它们可以丢失信息并从这种情况中恢复?

也许我的问题没有意义。也许我还在以隔离、锁定和事务为王的“单体”方式思考。

【问题讨论】:

  • 我认为所有队列都支持“确认”(或其他一些将更新偏移量的操作)基本上,如果您需要确保收到并处理您的流程,您的流程将是:1. 轮询 2. 处理3.承认
  • 如果对 (1) 和 (2) 感到迷恋,您已经确认 (3)。如果您的进程在发送确认消息之前被破坏,Broker 仍然会认为该消息未由客户端处理。关于 (3) - 实际上我认为这一步可能会引起您的担忧,不幸的是,我无法驱散它。
  • 我猜你知道分布式事务!

标签: java transactions microservices message-queue


【解决方案1】:

正如 Ivan Baranuk 在评论中所说。大多数消息代理都有acknowledgement。和死信队列 (DLQ)。

只要崩溃发生在acknowledgement 之前(可以由您正在使用的库处理,或者您可以手动处理),您就不会丢失您的消息,因为它会重新排队。如果多次后崩溃仍然发生并且超过maxRetryAttempt,它将被传递给DLQ以供您处理。

就像队列确认等同于数据库提交。

额外:我确实认为 DB 事务在使用消息时很重要。处理在使用消息时有多个 DB 写入的情况,然后在进程中间您的应用程序崩溃。当它崩溃时,消息不会是ack-ed,它会被重新排队,稍后会再次被消费。是为了防止消息第二次被消费时重复写入。

【讨论】:

  • 我认为你是对的。最近几天我读了很多书,重点是要避免 2PC 的“安全而缓慢”的技术(例如 JMS)。现在,使用 IDEMPOTENT 消息和您指示的 ACK 策略应该没有问题。
猜你喜欢
  • 2023-03-11
  • 2018-08-03
  • 2020-10-01
  • 2020-01-06
  • 2019-08-13
  • 1970-01-01
  • 2014-08-31
  • 2020-03-06
  • 1970-01-01
相关资源
最近更新 更多