协调微服务

协调微服务的标准模式是什么?

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

比方说,我们有这样的东西:

  • 进销存
  • 装船

为了争论,让我们说一旦订单已经发货,应该创build发票。

在某个地方,某人按下GUI中的一个button,“我完成了,让我们来做这个!” 在一个经典的整体服务体系结构中,我会说有一个ESB处理这个,或者货运服务知道发票服务并且只是调用它。

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

我确实认为这可以被认为是高度意见的基础。 但有一个具体的一面,因为微服务不应该这样做。 所以必须有一个“定义应该做什么”,而不是以意见为基础。

射击。

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

在编排vs编排的第43页上,这本书说:

随着我们开始对越来越复杂的逻辑进行build模,我们必须处理跨越单个服务边界的pipe理业务stream程的问题。 而对于微服务,我们会比平时更快地达到这个限制。 […]在实际实施这个stream程时,我们可以遵循两种架构风格。 有了pipe弦乐队,我们依靠中央大脑来引导和推动这个过程,就像pipe弦乐队的指挥一样。 通过舞蹈编排,我们通知系统的每一个部分,并且让舞蹈演员find自己的方式,并在芭蕾舞剧中对周围的人做出反应。

这本书继续解释这两种风格。 编排风格更多地与SOA的编排/任务服务相对应,而编排风格则与Martin Fowler的文章中提到的哑pipe和智能端点相对应。

编排风格

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

让我们考虑一下这个stream程的编排解决scheme。 在这里,最简单的做法可能就是让我们的客户服务成为中心的大脑。 在创build时,它通过一系列请求/响应调用与忠诚点银行,电子邮件服务和邮政服务进行通话。 客户服务本身可以跟踪客户在这个过程中的位置。 它可以检查客户的账户是否已经设置,或发送的邮件,或邮递。 我们得到stream程图并将其直接build模成代码。 我们甚至可以使用为我们实现这个的工具,也许使用适当的规则引擎。 商业工具以业务stream程build模软件的forms存在。 假设我们使用同步的请求/响应,我们甚至可以知道每个阶段是否有效[…]这种编排方法的缺点是客户服务可能成为太多的中央pipe理机构。 它可以成为networking中心,也是逻辑起点的中心点。 我已经看到这种方法导致了一些聪明的“神”服务,告诉贫穷的基于CRUD的服务要做什么。

注:我想当作者提到工具时,他指的是像BPM (如Activity , Apache ODE )。 事实上, 工作stream模式网站有一套非常棒的模式来进行这种编排,同时还提供了不同供应商工具的评估细节,这些工具有助于以这种方式实施。 我不认为作者暗示需要使用这些工具之一来实现这种风格的集成,但是可以使用其他轻量级编排框架,例如Spring Integration , Apache Camel或Mule ESB

然而,我已经读过关于微服务主题的其他书籍 ,而且我在网上发现的大多数文章似乎都不喜欢这种编排方法 ,而是build议使用下一个。

编排风格

在编舞风格下,作者说:

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

注意:这听起来很像CQRS和EvenSourcing。 到目前为止,我还不确定舞蹈编排是不是事件驱动架构 (EDA)的另一个名称,但是如果EDA只是一种方法,那么其他方法是什么? (另请参阅“事件驱动”和“事件驱动体系结构 ” 的含义 )

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

那么,HATEOAS呢?

现在,如果我们想要遵循RESTful方法,我们不能忽视HATEOAS,否则Roy Fielding会非常高兴地在他的博客中说我们的解决scheme并不是真正的REST。 在REST API上查看他的博客文章必须是超文本驱动的 :

我感到沮丧的人调用任何基于HTTP的接口REST API的人数。 在超文本是一个约束的概念上,需要做些什么才能使REST架构风格变得清晰? 换句话说,如果应用程序状态(因此API)的引擎没有被超文本驱动,那么它不能是RESTful,并且不能是REST API。 期。 是否有某些需要修复的手册中断?

所以,正如你所看到的,Fielding认为,如果没有HATEOAS,你并不真正构buildRESTful应用程序。 为了实现HATEOAS,在协调服务的时候是一个很好的select。 我正在学习所有这些,但是对于我来说,HATEOAS并没有明确地界定究竟是谁或什么是实际遵循链接的驱动力。 在一个可能是用户的UI中,但是在计算机到计算机之间的交互中,我想这需要由更高层次的服务来完成。

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

尽pipe听起来有多酷,但客户端仍然需要知道链接是否必须被POST,PUTED,GET,PATCH等。客户端仍然需要决定通过哪个有效载荷。 客户仍然需要知道如果失败了,应该怎么做(重试,补偿,取消等)。

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

我想我们可以通过编排或编排来使用HATEOAS。

API网关模式

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

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

应用程序客户端(如本地移动应用程序)可以对各个服务进行RESTful HTTP请求[…]表面上看起来似乎很有吸引力。 但是,各个服务的API与客户所需的数据之间的粒度可能存在显着的不匹配。 例如,显示一个网页可能需要调用大量的服务。 例如,Amazon.com 描述了一些页面需要如何呼叫100多个服务。 即使通过高速互联网连接提出这么多的请求,更不用说较低带宽,更高延迟的移动networking,将是非常低效的并且导致不良的用户体验。

一个更好的方法是让客户端通过互联网向一个称为API网关的前端服务器提供每页less量的请求,可能只有一个。

API网关位于应用程序的客户端和微服务之间。 它提供了适合客户的API。 API网关为移动客户端提供粗粒度的API,为使用高性能networking的桌面客户端提供更细致的API。 在本例中,桌面客户端发出多个请求来检索有关产品的信息,其中移动客户端发出一个请求。

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

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

现在我们看看API网关如何在应用程序和客户端之间进行中介,现在让我们看看如何实现微服务之间的通信。

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

进一步阅读

最近在NGINX博客上发表了一系列文章,我build议深入研究所有这些概念:

  • 微服务简介
  • 构build微服务:使用API​​网关
  • 在微服务架构中构build微服务:IPC
  • 微服务架构中的服务发现
  • 事件驱动的微服务数据pipe理
  • select微服务部署策略
  • 将整体重构成微服务

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

域名事件

主要的做法似乎是使用域事件,其中每个服务发布关于发生的事件和其他服务可以订阅这些事件。 这似乎与马丁·福勒(Martin Fowler)在这里描述的聪明终结点的概念是一致的: http : //martinfowler.com/articles/microservices.html#SmartEndpointsAndDumbPipes

域事件

代理

另一个似乎很常见的应用是将业务stream程包装在自己的服务中。 代理如何协调微服务之间的交互,如下图所示:

代理

所以你有两个服务:

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

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

  • 一个简单的graphics用户界面知道您的所有服务和实施用例(“我完成”调用运送服务)
  • 业务stream程引擎,等待“我完成”事件。 这个引擎实现用例和stream程。
  • 一个编排微服务,让我们说订单处理服务本身,知道您的域的stream量/使用情况
  • 还有什么我还没有想过的

主要的一点是控制是外部的。 这是因为所有应用程序组件都是单独的构build块,松散耦合。 如果您的用例发生变化,您必须在一个地方更改一个组件,这就是编排组件。 如果添加不同的订单stream,则可以轻松地添加另一个不妨碍第一个的协调器。 微服务的思想不仅仅是可扩展性,做REST API,还要有一个清晰的结构,减less组件之间的依赖关系,以及在整个业务中共享的通用数据和function的重用。

HTH,Mark

那么,微服务的编排与SOA的服务编排有什么不同? 没有太多。

微服务通常使用http(REST)或消息/事件进行通信。 编排通常与使用BPEL或类似语言的编排平台相关联,以自动化工作stream程。 只要您的编排平台支持您的微服务中使用的通信机制,他们就可以参与编排。 但请记住,编排是一种复合模式,可提供多种function来创build复杂的服务组合。 微服务通常被认为是不应该参与复杂组合的服务,而应该更加自主。

我可以看到在协调工作stream中调用的微服务可以做一些简单的处理,但是我没有看到一个微服务就是协调器服务,它经常使用补偿事务和状态库(脱水)等机制。

如果需要pipe理国家 ,那么采用CQRS的事件采购是理想的沟通方式。 否则,asynchronous消息系统(AMQP)可以用于微服务间的通信。

从你的问题来看,很显然,使用CQRS的ES应该是正确的组合。 如果使用java,请查看Axon框架。 或者使用Kafka或RabbitMQ构build自定义解决scheme。