编排微服务

Orchestrating microservices

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

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

假设我们有这样的事情:

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

某处,有人在 GUI、"I'm done, let's do this!" 中按下按钮 在经典的单体服务架构中,我会说有一个 ESB 处理这个,或者 Shipment 服务知道发票服务并调用它。

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

我确实知道这可以被认为是高度基于意见的。但它有具体的一面,因为微服务不应该做上述事情。 所以必须有一个"what should it by definition do instead",它不是基于意见的。

射击。

所以您有两项服务:

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

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

  • 了解您的所有服务并实现用例的简单 GUI("I'm done" 调用发货服务)
  • 等待 "I'm done" 事件的业务流程引擎。该引擎实现用例和流程。
  • 一个编排微服务,假设订单处理服务本身知道您域的 flow/use 个案例
  • 还有什么我还没有想到的

这里的要点是控制是外部的。这是因为您的所有应用程序组件都是松散耦合的独立构建块。如果您的用例发生变化,您必须在一个地方更改一个组件,即编排组件。如果您添加不同的订单流,您可以轻松添加另一个不会干扰第一个的协调器。微服务思想不仅涉及可扩展性和做花哨的 REST API,还涉及清晰的结构、减少组件之间的依赖性以及在整个业务中共享的公共数据和功能的重用。

HTH,马克

尝试在此处汇总不同的方法。

领域事件

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

代理

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

.

其他构图模式

这个page包含各种构图模式。

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

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

As we start to model more and more complex logic, we have to deal with the problem of managing business processes that stretch across the boundary of individual services. And with microservices, we’ll hit this limit sooner than usual. [...] When it comes to actually implementing this flow, there are two styles of architecture we could follow. With orchestration, we rely on a central brain to guide and drive the process, much like the conductor in an orchestra. With choreography, we inform each part of the system of its job and let it work out the details, like dancers all find‐ ing their way and reacting to others around them in a ballet.

本书接着解释了这两种风格。编排风格更符合Martin Fowler文章中提到的orchestration/task services, whereas the choreography style corresponds to the dumb pipes and smart endpointsSOA思想

配器风格

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

Let’s think about what an orchestration solution would look like for this flow. Here, probably the simplest thing to do would be to have our customer service act as the central brain. On creation, it talks to the loyalty points bank, email service, and postal service [...], through a series of request/response calls. The customer service itself can then track where a customer is in this process. It can check to see if the customer’s account has been set up, or the email sent, or the post delivered. We get to take the flowchart [...] and model it directly into code. We could even use tooling that implements this for us, perhaps using an appropriate rules engine. Commercial tools exist for this very purpose in the form of business process modeling software. Assuming we use synchronous request/response, we could even know if each stage has worked [...] The downside to this orchestration approach is that the customer service can become too much of a central governing authority. It can become the hub in the middle of a web and a central point where logic starts to live. I have seen this approach result in a small number of smart “god” services telling anemic CRUD-based services what to do.

注意:我想当作者提到工具时,他指的是类似 BPM (e.g. Activity, Apache ODE, Camunda). As a matter of fact, the Workflow Patterns Website has an awesome set of patterns to do this kind of orchestration and it also offers evaluation details of different vendor tools that help to implement it this way. I don't think the author implies one is required to use one of these tools to implement this style of integration though, other lightweight orchestration frameworks could be used e.g. Spring Integration, Apache Camel or Mule ESB

的东西

不过,other books I've read on the topic of Microservices and in general the majority of articles I've found in the web seem to disfavor this approach编排,建议改用下一个。

编舞风格

编排风格下作者说:

With a choreographed approach, we could instead just have the customer service emit an event in an asynchronous manner, saying Customer created. The email service, postal service, and loyalty points bank then just subscribe to these events and react accordingly [...] This approach is significantly more decoupled. If some other service needed to reach to the creation of a customer, it just needs to subscribe to the events and do its job when needed. The downside is that the explicit view of the business process we see in [the workflow] is now only implicitly reflected in our system [...] This means additional work is needed to ensure that you can monitor and track that the right things have happened. For example, would you know if the loyalty points bank had a bug and for some reason didn’t set up the correct account? One approach I like for dealing with this is to build a monitoring system that explicitly matches the view of the business process in [the workflow], but then tracks what each of the services do as independent entities, letting you see odd exceptions mapped onto the more explicit process flow. The [flowchart] [...] isn’t the driving force, but just one lens through which we can see how the system is behaving. In general, I have found that systems that tend more toward the choreographed approach are more loosely coupled, and are more flexible and amenable to change. You do need to do extra work to monitor and track the processes across system boundaries, however. I have found most heavily orchestrated implementations to be extremely brittle, with a higher cost of change. With that in mind, I strongly prefer aiming for a choreographed system, where each service is smart enough to understand its role in the whole dance.

注意:直到今天我仍然不确定编舞是否只是 event-driven architecture (EDA), but if EDA is just one way to do it, what are the other ways? (Also see What do you mean by "Event-Driven"? and The Meanings of Event-Driven Architecture) 的别名。此外,CQRS 和 EventSourcing 之类的东西似乎与这种架构风格产生了很多共鸣,对吧?

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

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

现在,如果我们想遵循 RESTful 方法,我们就不能忽略 HATEOAS,否则 Roy Fielding 会非常高兴地在他的博客中说我们的解决方案不是真正的 REST。在 REST API Must be Hypertext Driven 上查看他的博客 post:

I am getting frustrated by the number of people calling any HTTP-based interface a REST API. What needs to be done to make the REST architectural style clear on the notion that hypertext is a constraint? In other words, if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API. Period. Is there some broken manual somewhere that needs to be fixed?

因此,如您所见,Fielding 认为如果没有 HATEOAS,您就无法真正构建 RESTful 应用程序。对于 Fielding 而言,HATEOAS 是编排服务的必由之路。我只是在学习这一切,但对我来说,HATEOAS 并没有明确定义真正跟随 links 的背后驱动力是谁或什么。在 UI 中可能是用户,但在计算机到计算机的交互中,我认为这需要由更高级别的服务来完成。

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

尽管这听起来很酷,但客户端仍然需要知道 link 是否必须 POSTed、PUTed、GETed、PATCHed 等。并且客户端仍然需要决定什么负载通过。客户端仍然需要知道如果失败该怎么办(重试、补偿、取消等)。

我对这一切还很陌生,但对我来说,从 HATEOA 的角度来看,此客户端或 API 消费者是一项高阶服务。如果我们从人的角度考虑,你可以想象网页上的最终用户,决定要遵循什么link,但是,网页的程序员仍然必须决定使用什么方法调用 links,以及要传递的负载。因此,就我而言,在计算机与计算机的交互中,计算机扮演着最终用户的角色。这就是我们所说的编排服务。

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

API 网关模式

Chris Richardson 提出了另一个有趣的模式,他还提出了他所谓的 API Gateway Pattern

In a monolithic architecture, clients of the application, such as web browsers and native applications, make HTTP requests via a load balancer to one of N identical instances of the application. But in a microservice architecture, the monolith has been replaced by a collection of services. Consequently, a key question we need to answer is what do the clients interact with?

An application client, such as a native mobile application, could make RESTful HTTP requests to the individual services [...] On the surface this might seem attractive. However, there is likely to be a significant mismatch in granularity between the APIs of the individual services and data required by the clients. For example, displaying one web page could potentially require calls to large numbers of services. Amazon.com, for example, describes how some pages require calls to 100+ services. Making that many requests, even over a high-speed internet connection, let alone a lower-bandwidth, higher-latency mobile network, would be very inefficient and result in a poor user experience.

A much better approach is for clients to make a small number of requests per-page, perhaps as few as one, over the Internet to a front-end server known as an API gateway.

The API gateway sits between the application’s clients and the microservices. It provides APIs that are tailored to the client. The API gateway provides a coarse-grained API to mobile clients and a finer-grained API to desktop clients that use a high-performance network. In this example, the desktop clients make multiple requests to retrieve information about a product, whereas a mobile client makes a single request.

The API gateway handles incoming requests by making requests to some number of microservices over the high-performance LAN. Netflix, for example, describes how each request fans out to on average six backend services. In this example, fine-grained requests from a desktop client are simply proxied to the corresponding service, whereas each coarse-grained request from a mobile client is handled by aggregating the results of calling multiple services.

Not only does the API gateway optimize communication between clients and the application, but it also encapsulates the details of the microservices. This enables the microservices to evolve without impacting the clients. For example, two microservices might be merged. Another microservice might be partitioned into two or more services. Only the API gateway needs to be updated to reflect these changes. The clients are unaffected.

Now that we have looked at how the API gateway mediates between the application and its clients, let’s now look at how to implement communication between microservices.

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

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

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

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

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

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

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

我写过几篇关于这个主题的文章:

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

API 网关模式 - 粗粒度 api 与细粒度 apis

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

粗粒度与细粒度服务API

By definition a coarse-grained service operation has broader scope than a fine-grained service, although the terms are relative. coarse-grained increased design complexity but can reduce the number of calls required to complete a task. at micro-services architecture coarse-grained may reside at the API Gateway layer and orchestrate several micro-services to complete specific business operation. coarse-grained APIs needs to be carefully designed as involving several micro-services that managing different domain of expertise has a risk to mix-concerns in single API and breaking the rules described above. coarse-grained APIs may suggest new level of granularity for business functions that where not exist otherwise. for example hire employee may involve two microservices calls to HR system to create employee ID and another call to LDAP system to create a user account. alternatively client may have performed two fine-grained API calls to achieve the same task. while coarse-grained represents business use-case create user account, fine-grained API represent the capabilities involved in such task. further more fine-grained API may involve different technologies and communication protocols while coarse-grained abstract them into unified flow. when designing a system consider both as again there is no golden approach that solve everything and there is trad-off for each. Coarse-grained are particularly suited as services to be consumed in other Business contexts, such as other applications, line of business or even by other organizations across the own Enterprise boundaries (typical B2B scenarios).

原题的答案是SAGA模式。

您可以使用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. 发送事件到状态机

请参阅文档页面以获取完整信息code