Chr*_*nte 5 distributed-computing cqrs event-sourcing microservices
假设我们有 3 个不同的服务生成事件,每个服务都发布到自己的事件存储。
这些服务中的每一个都会消耗其他生产者服务事件。这是因为每个服务都必须处理另一个服务的事件并创建自己的投影。每个服务都在多个实例上运行。
(对我来说)最直接的方法是在每个 ES 前面放置“一些东西”,它正在挑选事件并将它们发布(发布/订阅)到每个其他服务的队列中。
这是完美的,因为每个服务都可以订阅它喜欢的每个主题,而事件发布者正在执行这项工作,并且如果服务不可用,事件仍然会传递。在我看来,这保证了高可扩展性和可用性。
我的问题是队列。我无法获得一个可轻松扩展的队列来保证消息的排序。它实际上保证了至少一次交付的“轻微失序”:需要明确的是,它是 AWS SQS。
因此,排序问题是:
我想我可以通过跟踪来自同一 ES 的事件的“序列号”来解决前两个问题。这可以通过跟踪我们消费事件的每个主题的最后一个序列号来完成。这应该很容易对事件做出反应并构建我们的投影。然后,当我从队列中弹出一个事件时,如果eventSequenceNumber > previousAppliedEventSequenceNumber + 1我将其重新排队(或使其在一段时间内不可见)。
但事实证明,使用这个解决方案,当事件以高速率产生时,它会破坏性能(我可以使用可见性超时或其他东西,结果应该是相同的)。
这是因为当我期待事件 10 并暂时忽略事件 11 时,我还应该忽略序列号在事件 11 之后的所有事件(来自 ES),直到事件 11 再次出现并得到有效处理。
其他困难是:
lastSequenceNumber.我缺少什么?
PS:对于第三个问题,请考虑以下场景。我们有 aUserService和 a CartService。它CartService有一个投影,每个用户都可以跟踪购物车中的产品。UserCreated每个购物车的投影还必须包含来自.NET 发布的事件的用户名和其他信息UserService。如果UserCreated出现在ProductAddedToCart正常流程之后,则需要抛出异常,因为用户尚不存在。
\n\n\n我缺少什么?
\n
您缺少流程——消费者从源中提取消息,而不是让源将消息推送给消费者。
\n\n当我醒来时,我会检查我的书签,找出我最后读过的你的消息,然后问你此后是否有过。如果有,我会按顺序从您那里检索它们(想想“文档消息”),同时记下新书签。然后我就回去睡觉了。
\n\n推送通知的主要目的是中断睡眠周期(从而减少延迟)。
\n\n当 SQS 充当队列时,其想法是您可以立即读取所有排队的消息。如果没有间隙,那么您可以对集合进行排序,然后开始处理它们并确认它们。如果存在间隙,您要么等待(将消息留在队列中),要么前往事件存储来获取丢失消息的副本。
\n\n这并不神奇——如果消息管道承诺“至少一次”传递,那么消费者必须采取措施在重复消息到达时识别它们。
\n\n\n\n\n如果 UserCreated 在 ProductAddedToCart 之后,则正常流程需要抛出异常,因为用户尚不存在。
\n
回顾竞争条件不存在,作者:Udi Dahan:“时间上的一微秒差异不应该\xe2\x80\x99 对核心业务行为产生影响。”
\n| 归档时间: |
|
| 查看次数: |
1789 次 |
| 最近记录: |