东莞网站建设纸品包装,烟台企业展厅设计公司,网站做支付要多少钱,青岛做网站优化公司使用 Outbox 模式保持微服务数据一致性 在一个由许多小型服务组成的系统中保持数据一致性是困难的#xff0c;因为它们分散在各处。以下是一些常见问题以及如何处理它们的方法#xff1a;当服务发送消息时#xff0c;同时更新数据库和发送消息是棘手的问题。 在微服务中发出… 使用 Outbox 模式保持微服务数据一致性 在一个由许多小型服务组成的系统中保持数据一致性是困难的因为它们分散在各处。以下是一些常见问题以及如何处理它们的方法当服务发送消息时同时更新数据库和发送消息是棘手的问题。 在微服务中发出事件时我们必须解决如何以事务方式更新数据库并发出事件的问题。 Outbox 模式 处理这个问题的简单方法是使用事务性 Outbox 模式。 1*4ApYkrLX-KMWMqLZs1Ea9Q.png 问题双写问题 当我们必须同时更新两个不同的系统时就会出现双写问题。例如如果我们需要在 Apache Kafka 和数据库中记录事件。由于这些系统没有连接我们无法一次性更新它们。我们必须找到一种方法来确保两者同时更新或者两者都不更新。这就是事务性 Outbox 模式发挥作用的地方。 如果我们的数据库支持事务性更新我们可以使用它来解决双写问题。我们将事务逻辑移到数据库中而不是尝试同时更新数据库和 Kafka。每当我们更新数据库时我们也在同一个事务中更新一个 Outbox 表。可以将 Outbox 想象成一个邮箱我们将需要发送的信件放在其中。然后我们等待邮递员收集这些信件并将其送到邮局。在我们的情况下这些信件代表我们想要发送到 Kafka 的事件而 Kafka 则充当邮局。但是我们仍然需要某种东西扮演邮递员的角色。 要从 Outbox 表中发出事件到 Apache Kafka我们可以使用一个单独的进程来异步监视该表。每当它检测到事件时就可以将其发送到 Kafka。 1*bF5bu2znS9hSZOLGG5i56w.png 双写问题 一旦事件成功传递它就可以从 Outbox 表中删除。该进程通常是在原始微服务中的另一个线程中编写的但是它也可以作为完全独立的应用程序运行。根据您使用的数据库您可能可以使用 Kafka 连接器例如 Postgres-Kafka 连接器或更改数据捕获CDC系统例如 Debezium来监视表并发送事件。 1*LIIuyIzUQ6owQY81k5LqRg.png Kafka 连接器或更改数据捕获CDC 使用 CDC 解决双写问题的优势 Outbox 事务模式避免了双写问题。原因是状态和 Outbox 表将始终以事务方式更新。如果由于某种原因状态未能更新则事件不会写入 Outbox这意味着我们可以保证 Outbox 中的数据与数据库中的数据完全同步。然后负责将事件传递到 Kafka 的独立进程确保 Outbox 表和 Kafka 保持同步。这使我们能够保证每个数据库操作都会在 Kafka 中有一个相应的事件尽管会有一点延迟。 缺点当传递过程向 Kafka 发出事件时可能会出现失败或超时。在这种情况下为了确保 Kafka 收到数据我们必须重试。这些重试可能导致重复的消息因此我们向 Kafka 的传递保证是至少一次的。我们保证 Outbox 中的每条消息最终都会到达 Kafka但可能会重复到达。因此我们需要确保下游系统准备好处理任何重复消息。 在分布式系统中至少一次的保证是常见的因此即使不涉及双写问题实现去重逻辑也是一个良好的做法。例如接收方在处理 Kafka 消息时可能会失败并且当它重新启动时可能会再次收到相同的消息。 1*Q3y3m680RrZ05SevzCY2Og.png Outbox 模式中的挑战 我们必须准备好处理这些情况。这可能会导致大量的流量。频繁的更新意味着数据库可能会始终将表保存在内存中占用大量资源。与此同时一些数据库在处理删除时效率不高。它们可能在幕后使用墓碑并且随着频繁的插入和删除发生这些墓碑可能会累积这会导致资源使用量大增并在我们的表中引起争用。如果数据库无法处理此类流量可能会减慢我们的应用程序因为请记住每个写入都将触及该 Outbox 表。为了解决这些问题我们可能需要进行调整例如将记录而不是删除它们或者调整数据库管理墓碑的方式。保留事件可能会带来长期的好处因此删除可能并非绝对必要。一些数据库专门设计用于处理这种类型的流量。 结论 如果您的系统满足事务性 Outbox 模式的要求那么它可以是解决双写问题的一种简单有效的方法。与其他选项例如事件溯源或监听自己模式相比这种方法采用事件优先的方法使用 Kafka 实时通知微服务变更保持系统一致性。但是诸如订单履行之类的组件可能需要编排无法运行。