首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >消息幂等性排序注意事项

消息幂等性排序注意事项
EN

Stack Overflow用户
提问于 2018-10-05 16:33:54
回答 1查看 1.2K关注 0票数 4

假设我们有一个系统,如果有一个生产者在队列中排队消息,以及多个处理这个事件的消费者实例。由于我们处于一种相互竞争的消费者模式中,我们知道订单不再是有保障的。这意味着我们必须确保我们的信息是幂等的。

根据我所读到的这里 (在消息排序要点下),我们必须确保消息处理是幂等的。

以下是问题:

  • 我们如何设计我们的消息处理是幂等的?
  • 如果我们在事件存储中保存每个事件,那么在设计每个事件的有效负载和事件聚合以获得聚合状态时,是否需要考虑到什么因素?

一个示例:假设我们有一个“用户创建”和一个“用户删除”消息(或任何其他需要按顺序处理的事件)。如果我们在“用户创建”之前处理“用户删除”,用户将不会被删除。即使他们是在事件队列中订购的。真正的幂等处理/幂等事件能给被删除的用户吗?

,另一个例子,。假设我们有一个具有score属性的实体。用户可以修改分数。第二服务消耗“评分实体”服务的事件,如果得分达到100,则由第二服务在“最佳类别”实体中插入实体(或实体引用)。如果得分达到-20,则第二个服务在“更糟的类别”中插入得分实体。如果“分数100”和“得分-20”事件在一个很短的时间间隔内,那么拥有第二个服务的多个实例就会产生不可预测的结果。对于如何设计“得分x”事件或如何处理这些事件,有什么想法吗?

非常感谢你的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-08 07:15:04

我们如何设计我们的消息处理是幂等的?

您应该:

  • 忽略您已经“看到”的消息;这意味着使用者应该有一种检测该消息的方法;例如,它可以保留它处理过的消息ID列表(这意味着每个消息都应该有一个唯一的ID)。
  • 如果消息不更改状态,则不要抛出异常;例如,如果收到第二个DeleteUser事件(因此用户已经被删除,第二个删除应该没有副作用),则忽略它。不是每个事件都可以是幂等的,例如,UpdateUserName不应该是幂等的。

如果我们在事件存储中保存每个事件,那么在设计每个事件的有效负载和事件聚合以获得聚合状态时,是否需要考虑到什么因素?

您应该基于您的域设计事件;有效负载不应该包含比域需要的更多的信息。如果附加信息将使您的重新模型更易于实现,那么您可以将其添加到有效负载中,但要小心将其标记为冗余。

例如:假设我们有“用户创建”和“用户删除”消息(或任何其他需要按顺序处理的事件)。如果我们在“用户创建”之前处理“用户删除”,用户将不会被删除。即使他们是在事件队列中订购的。真正的幂等处理/幂等事件能给被删除的用户吗?

在这种情况下,您可以拥有一个额外的已删除用户集合;您只能保留他们的ID。当CreateUser事件到达时,您可以通过查看DeletedUsers集合来检查用户是否已经被删除,如果用户在那里,则忽略它。您可以忽略为该用户提供的所有其他事件。

此解决方案非常依赖于域。

另一个例子。假设我们有一个具有score属性的实体。用户可以修改分数。第二服务消耗“评分实体”服务的事件,如果得分达到100,则由第二服务在“最佳类别”实体中插入实体(或实体引用)。如果得分达到-20,则第二个服务在“更糟的类别”中插入得分实体。如果“分数100”和“得分-20”事件在一个很短的时间间隔内,那么拥有第二个服务的多个实例就会产生不可预测的结果。对于如何设计“得分x”事件或如何处理这些事件,有什么想法吗?

这种情况可以通过将时间戳/订单/流-版本/任何上次处理的事件保持在/附加到重新模型(两个集合,bestworse)中来解决,并忽略小于或等于该时间戳的每个事件。这样,如果“分数100”在“得分-20”之后发出,但首先到达,则应该忽略“得分-20”,因为它具有较低的时间戳,尽管它排在最后。

这个解决方案是通用的,但它依赖于某种排序的存在。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52669913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档