design-patterns - 微服务架构 - 当订单无关紧要时通过服务传递消息

标签 design-patterns architecture rabbitmq message-queue microservices

Tl;博士 :“我如何通过一堆异步、无序的微服务推送消息,并知道该消息何时通过它们中的每一个?”

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

Diagram

  • 我在开始队列上有一条消息。假设一个带有序列化 JSON 的 RabbitMQ 消息
  • 我需要该消息通过任意数量的微服务
  • 这些微服务中的每一个都是长期运行的,必须是独立的,并且可以用多种语言实现
  • 消息通过的服务顺序无关紧要。事实上,它不应该是同步的。
  • 每个服务都可以将数据附加到原始消息,但其他服务会忽略该数据。不应该有合并冲突(每个服务写入一个唯一的 key )。任何服务都不会更改或破坏数据。
  • 轮到所有服务后,应该将消息与原始数据和新数据一起发布到第二个 RabbitMQ 队列。
  • 微服务不会有其他副作用。如果这一切都在一个单一的应用程序中(并且使用相同的语言),那么函数式编程将是完美的。

  • 那么,问题是,通过各种服务管理该消息的适当方法是什么?我 不要想要一次做一个,顺序并不重要。但是,如果是这种情况,系统如何知道所有服务何时完成,最终消息可以写入结束队列(让下一批服务开始运行)。

    我能想出的唯一、半优雅的解决方案是
  • 让第一个遇到消息的服务将该消息写入公共(public)存储(例如 mongodb)
  • 让每个服务都做它的事情,标记它已完成该消息,然后检查是否所有服务都已轮到
  • 如果是这样,最后一个服务将发布消息

  • 但这仍然要求每项服务都了解所有其他服务,并要求每项服务都留下自己的印记。这些都不是所希望的。

    我对某种“牧羊人”服务持开放态度。

    我会感谢我错过的任何选项,并愿意承认它们可能是更好的基本设计。

    谢谢你。

    最佳答案

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

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

    这个article解释了这两种风格的好处和权衡。

    编排
    Orchestration

    编排优势

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

  • 编排权衡
  • 将服务耦合在一起创建依赖关系。如果服务 A 宕机,服务 B 和 C 将永远不会被调用。
  • 如果所有请求都有一个协调器的中央共享实例,那么协调器就是一个单点故障。如果它发生故障,则所有处理都将停止。
  • 利用阻止请求的同步处理。在此示例中,端到端的总处理时间是调用服务 A + 服务 B + 服务 C 所用时间的总和。

  • 编舞
    Choreography

    编舞福利
  • 支持更快的端到端处理,因为服务可以并行/异步执行。
  • 更容易添加/更新服务,因为它们可以轻松地插入/退出事件流。
  • 与敏捷交付模型非常吻合,因为团队可以专注于特定服务而不是整个应用程序。
  • 控制是分布式的,因此不再有单个协调器充当故障中心点。
  • 几种模式可以与响应式(Reactive)架构一起使用,以提供额外的好处。例如,事件溯源是指事件流存储所有事件并启用事件重放。这样,如果服务在事件仍在产生时出现故障,当它重新上线时,它可以重播这些事件以 catch 。此外,可以应用命令查询职责分离 (CQRS) 来分离读取和写入事件。这使得这些中的每一个都可以独立缩放。如果您的应用程序读取量大而写入量少,反之亦然,这会派上用场。

  • 编排权衡
  • 对于开发人员来说,异步编程通常是一个重大的思维转变。我倾向于认为它类似于递归,您无法仅通过查看代码就知道代码将如何执行,您必须考虑在特定时间点可能发生的所有可能性。
  • 复杂性被转移。流程控制不再集中在编排器中,而是现在被分解并分布在各个服务中。每个服务都有自己的流逻辑,该逻辑将根据事件流中的特定数据确定何时以及如何使用react。
  • 关于design-patterns - 微服务架构 - 当订单无关紧要时通过服务传递消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47918407/

    相关文章:

    android - Android 上的 Couchbase lite - 通用架构?

    rest - REST API 支持的 backbone.js 应用程序的后端架构?

    Spring RabbitTemplate 未使用 TTL 创建死信队列

    RabbitMQ 镜像队列和交换

    javascript - Node.js 和 amqp 的 ETIMEDOUT 问题

    oop - 了解简洁代码示例中的单一责任主体 SRP

    javascript - 如何在网站上实现 "drag n drop"用户界面?

    oop - 每个 Facade 都应该作为 Singleton 实现吗?

    design-patterns - 设计模式

    types - 设计模式 : Question about "Types"