【问题标题】:What's the value of concurrency for sagas?sagas 的并发性有什么价值?
【发布时间】:2020-07-17 09:01:11
【问题描述】:

我不明白 saga 并发消息的目的。我希望它表现得更像一个演员。因此,所有具有相同CorrelationId 的消息都是按顺序处理的。 saga 的全部目的是编排一个长时间运行的进程,那么为什么并行消息处理很重要呢?

您能举一个合法的例子,说明与顺序模式相比,为 saga 实例并发处理消息是有益的吗?

还是我理解错了,并发仅仅意味着几个不同的saga实例并行运行?

问的原因是来自NServiceBusdocs的这个片段:

避免从外部资源访问数据的主要原因是saga state的可能争用和不一致。根据持久化器,可​​检索 saga 状态并使用悲观或乐观锁定进行持久化。 如果事务花费的时间太长,则可能会出现另一条与同一个 saga 实例相关的消息。它可能在不同的(并发)线程(或者可能是横向扩展的端点)上处理,并且它要么立即失败(悲观锁定),要么尝试保持状态(乐观锁定)。在这两种情况下,消息都会被重试。

【问题讨论】:

    标签: nservicebus masstransit


    【解决方案1】:

    没有,单个 saga 实例的消息需要按顺序处理。 MassTransit 中的 saga 配置没有什么特别之处,您真的想为其使用单独的端点并将并发限制设置为 1。

    但这会降低处理不同 saga 实例的消息的性能。为了解决这个问题,保持并发限制高于一,并使用相关 id 的分区过滤器。不幸的是,分区过滤器需要按消息配置,因此您需要为 saga 使用的所有消息配置分区。

    但这一切都取决于用例。当使用基于持久性的乐观并发时,所有并发问题都通过重试来解决,每个 saga 持久性提供者都记录了这一点。当然,重试数据库操作会产生一些噪音,但如果重试次数在控制范围内,则可以保持原样。

    如果您因大量并发更新而重试大量,您可以恢复为您的 saga 分区。

    【讨论】:

    • 好的,我明白了。原则上,多台机器处理 sagas 是可能的,所以还是有并发的。
    • 正确, saga 实例存在并发,但不在同一个实例中。 MassTransit(或我认为是 NSB)通过相关 ID 将消息序列化到同一个 saga 实例。如果使用乐观并发,一个实例可能会从两条单独的消息中加载和运行(其中一条在数据库更新被拒绝时被丢弃),因此在选择持久性机制时请记住这一点。
    • 避免不同实例之间的并发需要协调,这会带来很多复杂性。虽然理论上可以实现,但实际的解决方案通常只是放手,使用乐观并发,强制实例重试。
    • 我还要补充一点,对于 MT 7 和 Riders,应该可以使用一些更高级的代理,例如 Pulsar 及其针对固定消费者的功能。也许 RMQ 路由键可以类似地工作。
    猜你喜欢
    • 2023-03-24
    • 1970-01-01
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-25
    • 2023-04-06
    • 1970-01-01
    相关资源
    最近更新 更多