Design patterns 微服务体系结构-在订单不满足时通过服务传递消息';没关系

Design patterns 微服务体系结构-在订单不满足时通过服务传递消息';没关系,design-patterns,architecture,rabbitmq,message-queue,microservices,Design Patterns,Architecture,Rabbitmq,Message Queue,Microservices,Tl;dr:“我如何通过一组异步、无序的微服务推送消息,并知道消息何时通过其中的每一个服务?” 我正在努力为特定的微服务体系结构找到合适的消息传递系统/协议。这不是一个“哪一个是最好的”问题,而是一个关于设计模式/协议的选项的问题 我在开始队列上有一条消息。让我们假设一个带有序列化JSON的RabbitMQ消息 我需要这条信息通过任意数量的微服务 这些微服务中的每一个都是长期运行的,必须是独立的,并且可以用多种语言实现 消息通过的服务顺序并不重要。事实上,它不应该是同步的 每个服务都可以将数

Tl;dr:“我如何通过一组异步、无序的微服务推送消息,并知道消息何时通过其中的每一个服务?”

我正在努力为特定的微服务体系结构找到合适的消息传递系统/协议。这不是一个“哪一个是最好的”问题,而是一个关于设计模式/协议的选项的问题

  • 我在开始队列上有一条消息。让我们假设一个带有序列化JSON的RabbitMQ消息
  • 我需要这条信息通过任意数量的微服务
  • 这些微服务中的每一个都是长期运行的,必须是独立的,并且可以用多种语言实现
  • 消息通过的服务顺序并不重要。事实上,它不应该是同步的
  • 每个服务都可以将数据附加到原始消息中,但其他服务会忽略该数据。不应存在合并冲突(每个服务写入一个唯一的密钥)。任何服务都不会更改或销毁数据
  • 一旦所有服务都轮到它们,消息应该发布到第二个RabbitMQ队列,其中包含原始数据和新数据
  • 微服务不会有其他副作用。如果这些都在一个单片应用程序中(并且使用相同的语言),函数式编程将是完美的
因此,问题是,通过各种服务管理该消息的适当方式是什么?我不想一次做一个,而且顺序也不重要。但是,如果是这样的话,系统如何知道所有服务何时都被击中,最后的消息可以写入结束队列(以便让下一批服务开始)

我能想出的唯一半优雅的解决办法是

  • 让第一个遇到消息的服务将该消息写入公共存储(比如mongodb)
  • 让每个服务完成它的工作,标记它已完成该消息,然后检查是否所有服务都已轮到它们
  • 如果是这样,最后一个服务将发布消息
  • 但这仍然要求每个服务了解所有其他服务,并要求每个服务留下自己的印记。这两个都不可取

    我愿意接受某种“牧羊人”服务

    如果我错过了任何选择,我将不胜感激,我愿意承认,它们可能是一个更好的基本设计


    谢谢。

    管理长时间运行的流程(或涉及多个微服务的流程)有两种方法:编排和编排。有很多文章描述它们

    长话短说:在编排中,您有一个跟踪流程状态的微服务,在编排中,所有微服务都知道下一个消息发送到哪里和/或流程何时完成

    这就解释了这两种风格的好处和利弊

    编排

    编排的好处

    • 提供了一种在有同步处理时控制应用程序流的好方法。例如,如果服务A需要在调用服务B之前成功完成
    编排权衡

    • 将服务耦合在一起,创建依赖项。如果服务A关闭,则永远不会调用服务B和C

    • 如果所有请求都有orchestrator的中心共享实例,则orchestrator是单点故障。如果它下降,所有处理都停止

    • 利用阻止请求的同步处理。在本例中,总的端到端处理时间是调用服务A+服务B+服务C所需的时间之和

    编舞

    编舞的好处

    • 支持更快的端到端处理,因为服务可以并行/异步执行

    • 更容易添加/更新服务,因为它们可以很容易地插入/退出事件流

    • 与敏捷交付模型保持一致,因为团队可以专注于特定的服务,而不是整个应用程序

    • 控件是分布式的,因此不再有单个编排器充当故障中心点

    • 有几种模式可以与反应式体系结构一起使用,以提供额外的好处。例如,事件源是指事件流存储所有事件并启用事件重播。这样,如果一个服务在事件仍在生成时宕机,当它重新上线时,它可以重播这些事件以赶上进度。此外,还可以应用命令查询责任分离(CQRS)来分离读写活动。这使得每一个都可以独立地进行缩放。如果您的应用程序读重写轻,或者写重写轻,那么这就很方便了

    编舞权衡

    • 异步编程通常是开发人员重要的思维转变。我倾向于将其视为类似于递归,在递归中,你不能仅仅通过查看它来了解代码将如何执行,你必须仔细考虑在特定时间点可能出现的所有可能性

    • 复杂性被转移了。流控制不再集中在orchestrator中,而是被分解并分布在各个服务中。每个服务都有自己的流逻辑,该逻辑将根据事件流中的特定数据确定何时以及如何做出反应


    我会遵循常见的存储理念

    让每个微服务向公共sto注册自身