228

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

如果一个微服务只知道自己的领域,但是有一个数据流需要多个服务以某种方式交互,那该怎么做呢?

假设我们有这样的事情:

  • 发票
  • 运输

为了便于讨论,假设一旦订单发货,就应该创建发票。

在某个地方,有人按下了一个按钮GUI,“我完成了,让我们开始吧!” 在经典的单体服务架构中,我会说要么有一个ESB处理这个,要么发货服务知道发票服务并调用它。

但是在这个勇敢的微服务新世界中,人们如何处理这个问题?

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

射击。

4

8 回答 8

346

Book Building Microservices详细描述了@RogerAlsing 在他的回答中提到的样式。

在第 43 页的编排与编排下,这本书说:

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

然后本书继续解释这两种风格。编排风格更对应于 SOA 的编排/任务服务理念,而编排风格对应于 Martin Fowler 文章中提到的哑管道和智能端点。

编排风格

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

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

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

但是,我读过的其他有关微服务主题的书籍以及我在网络上找到的大多数文章似乎都不赞成这种编排方法,而是建议使用下一种。

编舞风格

在编舞风格下,作者说:

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

注意:直到今天,我仍然不确定编排是否只是事件驱动架构(EDA) 的另一个名称,但如果 EDA 只是实现它的一种方式,那么其他方式是什么?(另请参阅“事件驱动”是什么意思?事件驱动架构的含义)。此外,CQRS 和 EventSourcing 之类的东西似乎与这种架构风格产生了很大的共鸣,对吧?

现在,在这之后是乐趣。《微服务》一书并未假设微服务将使用 REST 实现。事实上,在本书的下一节中,他们继续考虑基于 RPC 和 SOA 的解决方案,最后是 REST。这里重要的一点是,微服务并不意味着 REST。

那么,HATEOAS 呢? (超媒体作为应用程序状态的引擎)

现在,如果我们想遵循 RESTful 方法,我们不能忽略 HATEOAS,否则 Roy Fielding 会非常高兴地在他的博客中说我们的解决方案并不是真正的 REST。请参阅他关于REST API 必须是超文本驱动的博客文章:

我对将任何基于 HTTP 的接口称为 REST API 的人数感到沮丧。需要做些什么来使 REST 架构风格清楚地认识到超文本是一种约束?换句话说,如果应用程序状态引擎(以及 API)不是由超文本驱动的,那么它就不能是 RESTful 并且不能是 REST API。时期。是否有一些损坏的手册需要修复?

因此,正如您所见,Fielding 认为没有 HATEOAS,您并没有真正构建 RESTful 应用程序。对于 Fielding,HATEOAS 是编排服务的最佳选择。我只是在学习这一切,但对我来说,HATEOAS 并没有明确定义谁或什么是实际遵循这些链接的驱动力。在可能是用户的 UI 中,但在计算机到计算机的交互中,我认为这需要由更高级别的服务来完成。

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

尽管这听起来很酷,但客户端仍然需要知道链接是否必须被 POST、PUT、GET、PATCHed 等。客户端仍然需要决定传递什么有效负载。客户端仍然需要知道如果失败该怎么办(重试、补偿、取消等)。

我对这一切都很陌生,但对我来说,从 HATEOA 的角度来看,这个客户端或 API 使用者是一个高阶服务。如果我们从人类的角度来思考,您可以想象网页上的最终用户,决定要遵循哪些链接,但是网页的程序员仍然必须决定使用什么方法来调用链接,以及要传递的有效载荷。因此,就我而言,在计算机对计算机的交互中,计算机扮演了最终用户的角色。这就是我们所说的编排服务。

我想我们可以将 HATEOAS 与编排或编排一起使用。

API 网关模式

另一个有趣的模式是 Chris Richardson 提出的,他还提出了他所谓的API 网关模式

在单体架构中,应用程序的客户端(例如 Web 浏览器和本机应用程序)通过负载均衡器向应用程序的 N 个相同实例之一发出 HTTP 请求。但在微服务架构中,单体应用已被服务集合所取代。因此,我们需要回答的一个关键问题是客户与什么互动?

应用程序客户端,例如本地移动应用程序,可以向各个服务发出 RESTful HTTP 请求 [...] 从表面上看,这似乎很有吸引力。但是,单个服务的 API 与客户端所需的数据之间的粒度可能存在严重的不匹配。例如,显示一个网页可能需要调用大量服务。例如,Amazon.com 描述了某些页面如何需要调用 100 多项服务。发出如此多的请求,即使是通过高速互联网连接,更不用说低带宽、高延迟的移动网络,也会非常低效并导致糟糕的用户体验。

更好的方法是让客户端通过 Internet 向称为 API 网关的前端服务器每页发出少量请求,可能只有一个。

API 网关位于应用程序的客户端和微服务之间。它提供了为客户端量身定制的 API。API 网关为移动客户端提供粗粒度 API,为使用高性能网络的桌面客户端提供更细粒度的 API。在此示例中,桌面客户端发出多个请求以检索有关产品的信息,而移动客户端发出单个请求。

API 网关通过在高性能 LAN 上向一些微服务发出请求来处理传入请求。例如,Netflix 描述 了每个请求如何平均分配到六个后端服务。在这个例子中,来自桌面客户端的细粒度请求被简单地代理到相应的服务,而来自移动客户端的每个粗粒度请求都是通过聚合调用多个服务的结果来处理的。

API 网关不仅优化了客户端和应用程序之间的通信,而且还封装了微服务的细节。这使微服务能够在不影响客户端的情况下发展。例如,可能会合并两个微服务。另一个微服务可能被划分为两个或多个服务。只有 API 网关需要更新以反映这些更改。客户不受影响。

既然我们已经了解了 API 网关如何在应用程序及其客户端之间进行中介,那么现在让我们看看如何实现微服务之间的通信。

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

于 2015-05-25T15:27:12.350 回答
42

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

领域事件

对此的主要方法似乎是使用域事件,其中每个服务发布有关已发生事件的事件,而其他服务可以订阅这些事件。这似乎与Martin Fowler 在此处描述的智能端点、哑管道的概念密切相关: http ://martinfowler.com/articles/microservices.html#SmartEndpointsAndDumbPipes

领域事件

代理人

另一个似乎很常见的方法是将业务流封装在它自己的服务中。代理协调微服务之间的交互,如下图所示:

代理.

其他构图模式

页面包含各种构图模式。

于 2015-03-20T08:57:50.523 回答
7

那么,微服务编排与非“微”的旧 SOA 服务编排有何不同?一点也不多。

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

请记住,编排是一种复合模式,它提供了多种功能来创建复杂的服务组合。微服务通常被视为不应该参与复杂组合的服务,而是更加自治的服务。

我可以看到在编排的工作流中调用微服务来执行一些简单的处理,但我没有看到微服务是编排服务,它经常使用诸如补偿事务和状态存储库(脱水)等机制。

于 2015-11-24T12:31:00.237 回答
6

So you're having two services:

  1. Invoice micro service
  2. Shipment micro service

In real life, you would have something where you hold the order state. Let's call it order service. Next you have order processing use cases, which know what to do when the order transitions from one state to another. All these services contain a certain set of data, and now you need something else, that does all the coordination. This might be:

  • A simple GUI knowing all your services and implementing the use cases ("I'm done" calls the shipment service)
  • A business process engine, which waits for an "I'm done" event. This engine implements the use cases and the flow.
  • An orchestration micro service, let's say the order processing service itself that knows the flow/use cases of your domain
  • Anything else I did not think about yet

The main point with this is that the control is external. This is because all your application components are individual building blocks, loosely coupled. If your use cases change, you have to alter one component in one place, which is the orchestration component. If you add a different order flow, you can easily add another orchestrator that does not interfere with the first one. The micro service thinking is not only about scalability and doing fancy REST API's but also about a clear structure, reduced dependencies between components and reuse of common data and functionality that are shared throughout your business.

HTH, Mark

于 2015-03-20T07:13:52.393 回答
1

如果需要管理状态,那么带有 CQRS 的事件溯源是理想的通信方式。否则,异步消息系统 (AMQP) 可用于微服务间通信。

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

于 2016-10-27T06:25:41.170 回答
0

您可以使用 spring状态机模型来实现编排。

脚步

  1. 将以下依赖项添加到您的项目中(如果您使用的是 Maven)

     <dependency>
         <groupId>org.springframework.statemachine</groupId>
         <artifactId>spring-statemachine-core</artifactId>
         <version>2.2.0.RELEASE</version>
     </dependency>
    
  2. 定义状态和事件,例如状态 1、状态 2 和事件 1 和事件 2

状态机

  1. 在buildMachine()方法中提供状态机实现。

    configureStates
    configureTransitions
    
  2. 向状态机发送事件

有关完整代码,请参阅文档页面

于 2021-09-21T09:45:48.093 回答
-2

我写了几篇关于这个主题的帖子:

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

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

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

粗粒度与细粒度服务 API

根据定义,粗粒度服务操作比细粒度服务具有更广泛的范围,尽管这些术语是相对的。粗粒度增加了设计复杂性,但可以减少完成任务所需的调用次数。在微服务架构中,粗粒度的可能驻留在 API Gateway 层,编排多个微服务来完成特定的业务操作。粗粒度的 API 需要仔细设计,因为它涉及多个微服务,管理不同的专业领域有可能在单个 API 中混合关注点并违反上述规则。粗粒度 API 可能会为原本不存在的业务功能提出新的粒度级别。例如,雇用员工可能涉及对 HR 系统的两次微服务调用以创建员工 ID 和对 LDAP 系统的另一个调用以创建用户帐户。或者,客户端可能已经执行了两个细粒度的 API 调用来完成相同的任务。粗粒度表示业务用例创建用户帐户,细粒度 API 表示此类任务涉及的功能。更细粒度的 API 可能涉及不同的技术和通信协议,而粗粒度将它们抽象成统一的流。在设计系统时,再次考虑两者,没有解决所有问题的黄金方法,并且每个都有权衡。粗粒度特别适合作为在其他业务上下文中使用的服务,例如其他应用程序,

于 2017-11-23T07:21:10.863 回答
-3

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

于 2018-03-06T01:44:28.177 回答