首页 文章

编排微服务

提问于
浏览
150

编排微服务的标准模式是什么?

如果微服务只知道它自己的域,但是有一个数据流要求多个服务以某种方式交互,那么它的方法是什么?

假设我们有这样的事情:

  • 开具发票

  • 装运

为了论证,让我们说一旦订单发货,就应该创建发票 .

在某个地方,有人按下GUI中的按钮,“我已经完成了,让我们这样做!”在一个经典的整体服务架构中,我会说有一个ESB处理这个,或者Shipment服务知道发票服务并且只是调用它 .

但是,在这个勇敢的微服务新世界中,人们处理这个问题的方式是什么?

我确实认为这可以被认为是基于意见的 . 但是它有一个具体的方面,因为微服务不应该做上述事情 . 所以必须有一个“定义应该做什么而不是”,这不是基于意见的 .

射击 .

7 回答

  • 27

    Building Microservices详细描述了@RogerAlsing在他的回答中提到的风格 .

    在Orchestration vs Choreography下的第43页上,该书说:

    当我们开始模拟越来越复杂的逻辑时,我们必须处理跨越各个服务边界的业务流程管理问题 . 使用微服务,我们会比平时更快地达到这个限制 . [...]当涉及到实际实现此流程时,我们可以遵循两种架构风格 . 通过编排,我们依靠中央大脑来指导和驱动这个过程,就像管弦乐队中的指挥一样 . 通过编排,我们告知系统的每个部分它的工作,并让它计算出细节,就像舞者们都在寻找自己的方式并在芭蕾舞中对周围的人做出反应 .

    然后,本书继续解释这两种风格 . 业务流程样式更多地与orchestration/task services的SOA思想相对应,而编排样式对应于Martin Fowler的文章中提到的dumb pipes and smart endpoints .

    Orchestration Style

    在这种风格下,上面的书提到:

    让我们考虑一下这个流程的编排解决方案 . 在这里,最简单的事情可能就是让我们的客户服务充当中心大脑 . 在创建时,它通过一系列请求/响应调用与忠诚度积分银行,电子邮件服务和邮政服务进行对话 . 然后,客户服务本身可以跟踪客户在此过程中的位置 . 它可以检查客户的帐户是否已设置,发送的电子邮件或发送的邮件 . 我们可以使用流程图[...]并将其直接建模到代码中 . 我们甚至可以使用为我们实现此功能的工具,也许使用适当的规则引擎 . 为此目的,商业工具以业务流程建模软件的形式存在 . 假设我们使用同步请求/响应,我们甚至可以知道每个阶段是否都有效[...]这种编排方法的缺点是客户服务可能变得太过中央管理机构 . 它可以成为Web中间的中心,也是逻辑开始生存的中心点 . 我已经看到这种方法导致少数智能“上帝”服务告诉贫血的基于CRUD的服务该做什么 .

    注意:我想当作者提到工具时,他指的是像BPM(例如ActivityApache ODECamunda) . 事实上,Workflow Patterns Website有一套很棒的模式来进行这种编排,它还提供了不同供应商工具的评估细节,有助于以这种方式实现它 . 我不认为作者暗示需要使用这些工具之一来实现这种集成方式,但是可以使用其他轻量级编排框架,例如, Spring IntegrationApache CamelMule ESB

    但是,在网络中找到的other books似乎是业务流程的disfavor this approach,而是建议使用下一个 .

    Choreography Style

    在编舞风格下,作者说:

    通过精心设计的方法,我们可以让客户服务以异步方式发出事件,称客户已创建 . 电子邮件服务,邮政服务和忠诚点银行然后只是订阅这些事件并做出相应的反应[...]这种方法明显更加分离 . 如果需要一些其他服务来创建客户,它只需要订阅事件并在需要时完成其工作 . 缺点是我们在[工作流程]中看到的业务流程的显式视图现在只能隐含地反映在我们的系统中[...]这意味着需要额外的工作来确保您可以监控和跟踪正确的事情 . 发生了 . 例如,您是否知道忠诚点银行是否有错误并且由于某种原因没有设置正确的帐户?我喜欢处理这个问题的一种方法是 Build 监控系统明确匹配[工作流程]中业务流程的视图,但随后跟踪每个服务作为独立实体的作用,让您看到映射到更明确的流程流程的奇怪异常 . [流程图] [...]不是驱动力,而只是一个镜头,通过它我们可以看到系统的行为方式 . 总的来说,我发现更倾向于编排方法的系统更松散地耦合,并且更灵活,更易于改变 . 但是,您确实需要执行额外的工作来监视和跟踪跨系统边界的进程 . 我发现大多数经过精心策划的实现都非常脆弱,而且更改成本更高 . 考虑到这一点,我更倾向于选择一个精心设计的系统,每个服务都足够聪明,可以理解它在整个舞蹈中的作用 .

    注意:到目前为止,我仍然不确定编排是否只是event-driven architecture(EDA)的另一个名称,但如果EDA只是一种方法,那么其他方法是什么? (另见What do you mean by "Event-Driven"?The Meanings of Event-Driven Architecture) . 此外,像CQRS和EvenSourcing这样的东西似乎与这种建筑风格产生了共鸣,对吗?

    现在,在这之后来了很有趣 . 微服务书并不假设微服务将通过REST实现 . 事实上,在本书的下一部分中,他们将继续考虑基于RPC和SOA的解决方案,最后考虑REST . 这里重点是微服务并不意味着REST .

    So, What About HATEOAS?

    现在,如果我们想要遵循RESTful方法,我们不能忽视HATEOAS或Roy Fielding将非常高兴地在他的博客中说我们的解决方案不是真正的REST . 在REST API Must be Hypertext Driven上查看他的博文:

    我对使用REST API调用任何基于HTTP的接口的人数感到沮丧 . 在超文本是一种约束的概念上,需要做些什么才能使REST架构风格清晰?换句话说,如果应用程序状态的引擎(以及API)不是由超文本驱动的,那么它就不能是RESTful而不能是REST API . 期 . 是否有某些需要修复的破损手册?

    所以,正如你所看到的,Fielding认为如果没有HATEOAS,你就不会真正构建RESTful应用程序 . 对于守备HATEOAS是协调服务的方法 . 我只是在学习这一切,但对我来说,HATEOAS没有明确定义实际跟踪链接背后的驱动力是谁或是什么 . 在可能是用户的UI中,但在计算机到计算机的交互中,我认为需要由更高级别的服务来完成 .

    根据HATEOAS,API消费者真正需要知道的唯一链接是启动与服务器通信的链接(例如POST /订单) . 从这一点开始,REST将进行流程,因为在此 endpoints 的响应中,返回的资源将包含指向下一个可能状态的链接 . 然后,API使用者决定要遵循的链接并将应用程序移动到下一个状态 .

    尽管听起来有多酷,但客户端仍然需要知道链接是否必须是POST,PUTed,GETed,PATCHed等 . 客户端仍需要确定要传递的有效负载 . 如果失败,客户端仍然需要知道该怎么做(重试,补偿,取消等) .

    我对这一切都很陌生,但对我来说,从HATEOAs的角度来看,这个客户端或API使用者是一个高级服务 . 如果我们从人的角度来思考它,你可以想象一个网页中的最终用户,决定要遵循的链接,但是网页的程序员还必须决定使用什么方法来调用链接,以及有效载荷通过 . 所以,就我而言,在计算机到计算机的交互中,计算机扮演最终用户的角色 . 再一次,这就是我们所谓的编排服务 .

    我想我们可以将HATEOAS用于编排或编排 .

    The API Gateway Pattern

    Chris Richardson提出了另一种有趣的模式,他也提出了他所谓的API Gateway Pattern .

    在单一体系结构中,应用程序的客户端(如Web浏览器和本机应用程序)通过负载均衡器向应用程序的N个相同实例之一发出HTTP请求 . 但在微服务架构中,monolith已被一系列服务所取代 . 因此,我们需要回答的一个关键问题是客户与之互动的内容是什么?应用程序客户端(例如本机移动应用程序)可以向各个服务发出RESTful HTTP请求[...]从表面上看,这似乎很有吸引力 . 但是,各个服务的API与客户端所需的数据之间的粒度可能存在显着的不匹配 . 例如,显示一个网页可能需要调用大量服务 . 例如,Amazon.com描述了某些页面如何需要调用100个服务 . 即使通过高速互联网连接,也可以提出这么多请求,更不用说低带宽,高延迟的移动设备了网络,效率非常低,导致用户体验不佳 . 一种更好的方法是客户端通过Internet向称为API网关的前端服务器发送每页(可能只有一个)的少量请求 . API网关位于应用程序的客户端和微服务之间 . 它提供了为客户量身定制的API . API网关为移动客户端提供粗粒度API,为使用高性能网络的桌面客户端提供更细粒度的API . 在此示例中,桌面客户端发出多个请求以检索有关产品的信息,而移动客户端在此处发出单个请求 . API网关通过高性能LAN向一些微服务发出请求来处理传入请求 . 例如,Netflix描述了每个请求平均如何扇出六个后端服务 . 在此示例中,来自桌面客户端的细粒度请求仅简单地代理到相应的服务,而来自移动客户端的每个粗粒度请求通过聚合调用多个服务的结果来处理 . API网关不仅可以优化客户端与应用程序之间的通信,还可以封装微服务的详细信息 . 这使得微服务能够在不影响客户端的情况下发展 . 例如,可以合并两个微服务 . 另一个微服务可能被划分为两个或更多服务 . 只需要更新API网关以反映这些更改 . 客户不受影响 . 现在我们已经了解了API网关如何在应用程序与其客户端之间进行协调,现在让我们看看如何在微服务之间实现通信 .

    这听起来非常类似于上面提到的编排风格,只是略有不同的意图,在这种情况下,它似乎都是关于性能和简化交互 .

    Further Reading

    最近在_773868中发表了一系列很多文章,我建议深入研究所有这些概念:

  • -1

    试图在这里汇总不同的方法 .

    域事件

    对此的主要方法似乎是使用域事件,其中每个服务发布有关已发生事件的事件,其他服务可以订阅这些事件 . 这似乎与Martin Fowler在这里描述的 smart endpoints, dumb pipes 的概念齐头并进:http://martinfowler.com/articles/microservices.html#SmartEndpointsAndDumbPipes

    Domain events

    代理

    另一个看起来很常见的应用是将业务流程包装在自己的服务中 . 代理协调微服务之间的交互,如下图所示:

    Proxies
    .

  • 4

    那么,微服务的编排与不是“微观”的旧SOA服务的编排有何不同?一点也不 .

    微服务通常使用http(REST)或消息/事件进行通信 . 业务流程通常与业务流程平台相关联,这些业务流程允许您在服务之间创建脚本化交互以自动化工作流 . 在旧的SOA时代,这些平台使用了WS-BPEL . 今天的工具不使用BPEL . 现代编排产品的示例:Netflix Conductor,Camunda,Zeebe,Azure Logic Apps,Baker .

    请记住,业务流程是一种复合模式,它提供了多种功能来创建复杂的服务组合 . 微服务通常被视为不应参与复杂组合而更自主的服务 .

    我可以看到在协调工作流中调用微服务来进行一些简单的处理,但我没有看到微服务是协调器服务,它通常使用诸如补偿事务和状态存储库(脱水)之类的机制 .

  • 5

    所以你有两个服务:

    • 发票微服务

    • 装运微服务

    在现实生活中,你会有一些你持有订单状态的东西 . 我们称之为订单服务 . 接下来,您有订单处理用例,它知道当订单从一种状态转换到另一种状态时该怎么做 . 所有这些服务都包含一组特定的数据,现在你需要其他的东西来完成所有的协调 . 这可能是:

    • 了解所有服务并实现用例的简单GUI("I'm done"调用货件服务)

    • 业务流程引擎,等待"I'm done"事件 . 该引擎实现了用例和流程 .

    • 一个编排微服务,假设订单处理服务本身知道你域名的流量/用例

    • 我还没有想到的任何其他事情

    对此的要点是控制是外部的 . 这是因为所有应用程序组件都是单独的构建块,松散耦合 . 如果您的用例发生更改,则必须在一个位置更改一个组件,即业务流程组件 . 如果你添加不同的订单流,您可以轻松添加另一个不干扰第一个的协调器 . 微服务思维不仅涉及可扩展性和花哨的REST API,还涉及清晰的结构,减少组件之间的依赖关系以及重用整个企业共享的通用数据和功能 .

    HTH,马克

  • 0

    如果需要管理 State ,那么使用CQRS的事件采购是理想的通信方式 . 此外,异步消息系统(AMQP)可用于微服务间通信 .

    从您的问题来看,显然具有CQRS的ES应该是正确的组合 . 如果使用java,请查看Axon框架 . 或者使用Kafka或RabbitMQ构建自定义解决方案 .

  • 234

    原始问题的答案是SAGA模式 .

  • 1

    我在这个主题上写了几篇文章:

    也许这些帖子也可以帮助:

    API网关模式 - 课程粒度api与细粒度api

    https://www.linkedin.com/pulse/api-gateway-pattern-ronen-hamias/ https://www.linkedin.com/pulse/successfulapi-ronen-hamias/

    粗粒度与细粒度服务API

    根据定义,粗粒度服务操作的范围比细粒度服务更广,尽管这些术语是相对的 . 粗粒度增加了设计复杂性,但可以减少完成任务所需的调用次数 . 在微服务架构中,粗粒度可以驻留在API网关层,并协调若干微服务以完成特定的业务操作 . 粗粒度API需要经过精心设计,因为涉及多个微服务,管理不同的专业领域存在混合问题的风险,这些问题涉及单个API并违反上述规则 . 粗粒度API可能会为业务功能建议新的粒度级别,否则就不存在 . 例如,雇员可能涉及两个微服务调用HR系统来创建员工ID,另一个调用LDAP系统来创建用户帐户 . 或者客户端可能已经执行了两次细粒度的API调用来实现相同的任务 . 粗粒度表示业务用例创建用户帐户,而细粒度API表示此类任务涉及的功能 . 更细粒度的API可能涉及不同的技术和通信协议,而粗粒度将它们抽象为统一流程 . 在设计系统时,再考虑两者都没有解决所有问题的黄金方法,并且每个方法都有传统 . 粗粒度特别适合作为其他业务环境中使用的服务,例如其他应用程序,业务线,甚至是跨越自身企业边界的其他组织(典型的B2B场景) .

相关问题