编排微服务


200

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

如果微服务仅了解其自己的域,但是有数据流需要多个服务以某种方式进行交互,那么该怎么办呢?

假设我们有这样的事情:

  • 开票
  • 装船

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

某处某人按下按钮GUI“我已经完成,让我们开始吧!” 在经典的整体式服务体系结构中,我会说要么进行ESB处理,要么运货服务具有发票服务的知识,然后就调用它。

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

我确实认为这可以认为是高度基于意见的。但是它有一个具体的方面,因为微服务不应该做到这一点。因此,必须有一个“根据定义应该做什么”,它不是基于观点的。

射击。

Answers:


316

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

在编排与编排下的第43页上,该书说:

当我们开始为越来越复杂的逻辑建模时,我们必须处理跨越单个服务边界的业务流程管理问题。借助微服务,我们将比平时更早达到此极限。[...]在实际实现此流程时,我们可以遵循两种样式。在编排过程中,我们就像在管弦乐队中的指挥一样,依靠中央大脑来引导和驱动过程。通过编舞,我们将系统的每个部分告知工作,并让其确定细节,就像舞者都在寻找自己的方式并对芭蕾舞中的其他人做出反应一样。

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

编排风格

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

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

注意:我想当作者提到工具时,他指的是类似BPM的东西(例如ActivityApache ODECamunda)。实际上,“ 工作流模式”网站提供了一组很棒的模式来进行这种编排,并且还提供了各种有助于以这种方式实施的供应商工具的评估详细信息。我认为作者并不暗示需要使用其中一种工具来实现这种集成风格,但是可以使用其他轻量级的编排框架,例如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等操作。客户端仍然需要确定要传递的有效负载。客户端仍然需要知道失败的处理方式(重试,补偿,取消等)。

我对这一切还算陌生,但是对我而言,从HATEOAs的角度来看,此客户端或API使用者是一项高级服务。如果我们从人类的角度考虑问题,您可以想象网页上的最终用户决定要遵循的链接,但是网页的程序员仍然必须决定使用哪种方法来调用链接,以及要传递的有效载荷。因此,就我而言,在计算机之间的交互中,计算机扮演了最终用户的角色。再一次,这就是我们所谓的业务流程服务。

我想我们可以在编排或编排中使用HATEOAS。

API网关模式

克里斯·理查森(Chris Richardson)提出了另一种有趣的模式,他也提出了他所谓的API网关模式

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

从表面上看,应用程序客户端(例如本机移动应用程序)可以向各个服务发出RESTful HTTP请求。但是,单个服务的API与客户端所需的数据之间的粒度可能存在严重的不匹配。例如,显示一个网页可能潜在地要求调用大量服务。例如,Amazon.com 描述了某些页面如何要求调用100多种服务。即使通过高速Internet连接发出这么多请求,更不用说带宽较低,延迟较高的移动网络了,这样的效率非常低,并且会导致不良的用户体验。

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

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

API网关通过在高性能LAN上向一定数量的微服务发出请求来处理传入的请求。Netflix的,例如, 描述 了每个请求平均如何分散到六个后端服务。在此示例中,来自桌面客户端的细粒度请求仅被代理到相应的服务,而来自移动客户端的每个粗粒度请求则通过汇总调用多个服务的结果来处理。

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

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

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


15
好答案!一个问题:如果我将编排风格的微服务与API网关结合使用,API网关是否不会变成您所描述的编排风格微服务的缺点的中央管理机构?或者,换句话说,“业务流程样式”与API网关模式之间的区别到底在哪里?
Fritz Duchardt

4
@FritzDuchardt不完全是。尽管api-gateway确实成为单点故障,但它不一定是任何类型的管理机构。一个非常简单的api网关可能只是对请求进行身份验证并将其代理到其目标服务。api-gateway模式主要用于简化通过单个服务的客户端与后端的交互,它并不能直接解决编排或编排API网关代理的服务(本身就是服务)的问题。
Porlune

好答案!关于API网关的一个问题:GraphQL是下一代API网关,并且很可能会取代API网关吗?
kenneho

我试图从实际的角度理解这一点。编排更松散地耦合->在这种情况下,应将eventListener动态添加到api方法吗?否则,如果不是,则每个api方法都将始终对接收到的事件做出反应(->因此不会松散耦合)
Vincent

我不同意舞蹈编排的松散耦合,因此需要通过微服务避免编排。我在berndruecker.io/complex-event-flows-in-distributed-systems中谈到了这一点。您需要在架构中采用更平衡的方法。
Bernd Ruecker

35

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

域事件

解决此问题的主要方法似乎是使用域事件,其中每个服务都发布有关已发生事件的事件,其他服务可以订阅这些事件。这似乎与马丁·福勒(Martin Fowler)在此处描述的智能端点,哑管道的概念紧密相关:http : //martinfowler.com/articles/microservices.html#SmartEndpointsAndDumbPipes

域事件

代理

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

代理人

构图的其他样式

页面包含各种构图模式。


这是一个很好的视频,其他模式是什么以及如何将它们组合在一起youtu.be/tSN1gOVQfPs?t=35m35s建议将它们添加到您的回复中
Grygoriy Gonchar 2015年

Nic images @Roger,您正在使用哪个工具?
Selvakumar Esra

1
@SelvakumarEsra draw.io
罗杰·约翰逊

7

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

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

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

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


应该注意的是,您帖子中的“今天的工具”仍然以某种形式利用事件,数据和活动来“建模”流程-camunda使用的是与BPEL接近的BPMN,而其他的则只是定义了自己的DSL来代表类似的概念。
Hightower

5

因此,您有两项服务:

  1. 发票微服务
  2. 出货微服务

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

  • 一个简单的GUI即可了解您的所有服务并实现用例(“我完成了”称为发货服务)
  • 业务流程引擎,等待“我完成”事件。该引擎实现了用例和流程。
  • 编排微服务,假设订单处理服务本身知道您域的流程/用例
  • 我还没想到的其他事情

重点是控件是外部的。这是因为您的所有应用程序组件都是松散耦合的单个构建基块。如果用例发生变化,则必须在一处更改一个组件,即业务流程组件。如果添加其他订单流程,则可以轻松添加另一个不会干扰第一个流程的协调器。微服务的思想不仅与可伸缩性和出色的REST API有关,还与结构清晰,组件之间的依赖性降低以及在整个企业中共享的通用数据和功能的重用有关。

HTH,马克


1

如果国家需要对进行管理,那么使用CQRS进行事件采购是一种理想的沟通方式。否则,异步消息传递系统(AMQP)可用于微服务间通信。

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


-2

我写了一些关于这个话题的文章:

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

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可能涉及不同的技术和通信协议,而粗粒度的抽象将它们抽象为统一流。在设计系统时,再一次考虑到了没有解决所有问题的黄金方法,并且每种方法都存在交易障碍。粗粒度特别适合在其他业务环境(例如其他应用程序)中使用的服务,


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.