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

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

假设我们有这样的东西:

发票 装运

为了便于讨论,让我们假设订单发出后,应该创建发票。

在某个地方,有人按下GUI中的一个按钮,“我完成了,让我们开始吧!” 在经典的整体服务体系结构中,我认为要么有ESB处理这个问题,要么发货服务了解发票服务并直接调用它。

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

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

开枪。


所以你有两个服务:

发票微服务 货运微服务

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

了解所有服务和实现用例的简单GUI(“我完成了”调用发货服务) 一个等待“I'm done”事件的业务流程引擎。这个引擎实现了用例和流程。 一个编配微服务,比如说订单处理服务本身,它知道你的领域的流程/用例 还有其他我没想过的吗

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,马克


试着把不同的方法聚合在一起。

域的事件

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

代理

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

.

其他组合模式

该页包含各种组合模式。


《构建微服务》一书详细描述了@RogerAlsing在他的回答中提到的风格。

在43页的编配vs编舞中,这本书说:

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.

这本书接着解释了这两种风格。编排风格更多地对应于编排/任务服务的SOA思想,而编排风格对应于Martin Fowler的文章中提到的哑管道和智能端点。

编排风格

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

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.

Note: I suppose that when the author mentions tooling he's referring to something like 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

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

编排风格

编舞风格下,作者说:

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.

注意:到目前为止,我仍然不确定编排是否只是事件驱动架构(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、PUTed、GETed、PATCHed等等。客户端仍然需要决定传递什么有效负载。客户端仍然需要知道如果失败了该做什么(重试、补偿、取消等等)。

I am fairly new to all this, but for me, from HATEOAs perspective, this client, or API consumer is a high order service. If we think it from the perspective of a human, you can imagine an end-user on a web page, deciding what links to follow, but still, the programmer of the web page had to decide what method to use to invoke the links, and what payload to pass. So, to my point, in a computer-to-computer interaction, the computer takes the role of the end-user. Once more this is what we call an orchestrations service.

我认为我们可以将HATEOAS用于编配或编排。

API网关模式

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

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

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

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


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

从你的问题可以看出,ES和CQRS应该是正确的组合。如果使用java,可以看看Axon框架。或者使用Kafka或RabbitMQ构建自定义解决方案。


关于这个话题,我写过几篇文章:

也许这些帖子也能有所帮助:

API网关模式——粗粒度API vs细粒度API

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

粗粒度服务API与细粒度服务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状态机模型来实现编排。

步骤

将以下依赖项添加到您的项目中(如果您使用Maven) <依赖> < groupId > org.springframework.statemachine < / groupId > < artifactId > spring-statemachine-core < / artifactId > <版本> 2.2.0.RELEASE > < /版本 < / >的依赖 定义状态和事件,例如状态1,状态2和事件1和事件2

在buildMachine()方法中提供状态机实现。 configureStates configureTransitions 将事件发送到状态机

请参阅文档页以获得完整的代码