[微服务技术文章之其一] 服务集成时需避免的两个错误

日常前言

  • 翻译任务终了,最近的项目也已经交付出去,现在剩下的就是一些历史遗留问题要慢慢和第三方沟通处理……开始进入真正的项目空闲期了。不过大概再有两个星期,就又要开始搞新的机型了,这次还是用的高通 SDM450 芯片,嗯…应该不会太忙。
  • 近期的主要任务是要学习 Android Camera HAL3 的流程,重点关注 Framework 以及 HAL 的部分,至少要搞懂 openCamera 流程,以及 takePicture 时候的控制流与数据流走向吧。到时候应该会整理资料,出个一系列的学习笔记。
  • 好吧,回到文章主题,这一期的内容,说实话吧,不是很感兴趣,而且我对微服务这方面也不熟悉,所以翻译的时候挺容易分心的。这次翻译主要就是练一练熟练度吧,也没记下太多笔记。觉得收获挺少的,希望下一期能来个我比较熟悉或者感兴趣的主题……
  • 以及,之前每一期的礼物,已经堆满衣柜顶了…要想办法处理出去了hh…
  • 这次只有两篇文章被采纳:

版权相关

翻译人:StoneDemo,该成员来自云+社区翻译社
原文链接:Two Mistakes You Need to Avoid When Integrating Services
原文作者:Pamod Sylvester


Two Mistakes You Need to Avoid When Integrating Services

题目:(服务集成时需避免的两个错误)

Key takeaways

(划重点)

  • Key factors that affect reliability of a system
  • Store and forward design pattern to preserve availability of a system
  • Latency impact of synchronous messaging and the reason to avoid it
  • Asynchronous communication using Linked Services pattern
  • Different acknowledgment patterns in brokering protocols/APIs i.e JMS and the reason for using them.
  • 影响系统可靠性的关键因素。
  • 采用存储转发(Store and forward)交换模式保持系统的可用性。
  • 同步消息传递(Synchronous messaging)中的延迟所产生的影响,以及需要避免它的原因。
  • 使用链接服务(Linked Services)模式的异步通信。
  • 在代理协议或 API (如 JMS)中的各种应答模式,以及为何要使用它们。

Introduction

(简介)

With the emergence of Service Oriented Architecture (SOA), businesses rapidly started transcending from their monolithic application designs into heterogeneous designs by decomposing their business functionality into multiple services [1]. Enterprise Architects should be careful when integrating these services together, as poorly integrated services would result in a spaghetti mess. Most often enterprises assume adopting to patterns such as Enterprise Service Bus (ESB) and Microservices alone would save them from this mess [2] and provide a viable solution. While it ‘partially’ does, unfortunately there are certain hidden challenges that these patterns alone do not address. The danger is that they typically go unnoticed during the initial stages of development and deployment, but surfaces when a system is live in production. By the time the consequences are realized, it might be too late. The intention of this article is to elaborate some of these challenges and articulate measures which could be taken to avoid them.

随着面向服务架构(下文简称 SOA,Service Oriented Architecture)的出现,企业通过将业务功能分解为多重服务 [1],它们迅速地从整体应用程序设计(Monolithic application design)过渡到了异构设计(Heterogeneous design)。在将这些服务集成起来之时,企业架构师应当小心,因为劣质的服务集成将会导致一团乱麻的结局。很多时候,企业假定仅采用如企业服务总线(下文简称 ESB,Enterprise Service Bus)和微服务这样的模式就能避免出现混乱的局面 [2],并且能够提供一个可行的解决方案。当它被 “部分地” 完成时,很不幸这些模式并不能解决某些隐藏的挑战。危险的是,在开发和部署的初始化阶段,它们通常不会被注意到,但是当系统在生产环境中工作时,它们就会出现。等我们意识到后果,为时已晚。本文旨在详细阐述其中的一些挑战,并明确指出,我们可以采取哪些措施来避免这些挑战。

Service Integration Challenges

(服务集成的挑战)

When adopting to SOA it’s common to use an ESB as the backbone infrastructure to integrate between services [3]. Well of course there’s sudden hype into using Microservices [4] as an alternative for ESB, nevertheless Anne Thomas (vice president and distinguished analyst at Gartner) doesn’t agree [5]. In my opinion, over granualizing services would adversely impact on the network overhead and also it makes it hard to debug and find faults of system. Therefore, it would be wise to move with Microservices with caution (unless making services granuler brings great benefits to the business). Nevertheless, the intention here is to elaborate the scope of the challenges addressed by these design patterns and reveal some of the hidden challenges which are not addressed by them.

在采用 SOA 时,我们通常使用 ESB 作为集成服务之间的主干基础设施 [3]。当然,现在用微服务作为 ESB 的替代品 [4] 这种方法突然就火起来了,然而,美国资讯公司高德纳的副总裁、杰出分析师 Anne Thomas 并不赞同 [5]。依我看来,过度的规模化服务会对网络开销产生负面影响,同时也会使系统的调试以及故障查找变得困难。因此,谨慎地使用微服务是明智的(除非服务粒度更大能为业务带来巨大的好处)。然而,本文目的是要详细说明这些设计模式所能解决的挑战的范围,并揭示一些它们没有解决的隐藏的挑战。

As illustrated in [1] the usage of Restful APIs keeps growing exponentially. Therefore, examples used in this article would mainly elaborate Restful API integrations done using ESB and uncover some of the hidden challenges which are not addressed through the ESB alone.

如文章 [1] 所述,Restful API 的使用数一直呈指数式增长。因此,本文中使用的示例将主要阐明应用 ESB 完成的 Restful API 集成,并揭示一些仅通过 ESB 无法解决的隐藏挑战。

Following illustrates a simple service chaining example done using the ESB. The user calls a proxy service in the ESB, where the role of the ESB is to chain between the two services Order Processing Service (OPS) and Order Delivery Service (ODS) and provide a response back to the user.

下面演示了一个使用 ESB 完成的简单服务链(Service chaining)示例。用户在 ESB 中调用代理服务,此时 ESB 的作用是将两个服务 —— 订单处理服务(下文简称 OPS,Order Processing Service)与订单交付服务(下文简称 ODS,Order Delivery Service)—— 将它们链接起来,并向用户提供响应。

图1. 披萨外卖系统

图2. 披萨外卖消息流

Listed below is a comparison of the benefits a user would get by using an ESB to integrate between the services. Instead of having the services directly talk to each other (point to point).

下表对比了用户通过使用 ESB 在服务之间集成(而非让服务直接彼此对话,即点对点的方式)所获得的好处。

这里写图片描述

特性 点对点 ESB
虚拟化/可用性 实现起来很复杂,每个客户端需要自己实现服务的编排/连接逻辑。 ESB 代理将 OPS 与 ODS 之间的链接虚拟化。则用户只需要调用 ESB 中的一个服务来获得预期的响应。
可扩展性 假设 OPS 服务是安全的,作为先决条件的服务需要在传入的请求中附加一个安全令牌。为获得一个安全令牌,用户授权服务(下文简称 UAS,User Authorization Service)应在 OPS 之前被调用。若有数百万客户端正调用 OPS,则这百万客户都必须修改他们的实现,以在 OPS 调用之前,先与 UAS 进行沟通。 客户端与服务编排/链接的复杂性并不紧密耦合。因此改变 ESB 中的配置就足以体现这一更改。
容错性 当服务之间是紧密耦合的,这会导致其中某一个服务出错时整个系统都会陷入危险之中。直接通信的情况下,在自动伸缩(Auto scaling)环境中进行容错处理以及负载均衡是很复杂的。 ESB 允许集中管理服务的编排/链接。因此,容错处理、节点自动伸缩的动态发现也可被集中管理。降低了用户/客户端开发的复杂性。

The above are some of the great benefits of using an ESB over point to point integration between the services, however, ESB alone do not solve all the challenges. The next sections would evaluate the challenges which are not addressed through the ESB alone.

上表罗列出了采用 ESB 比起点对点的服务集成所具有的主要优势。然而仅仅采用 ESB 并不能解决所有挑战。下一节将评估那些仅使用 ESB 不能解决的挑战。

By looking at the above example illustrated in Figure 1 and Figure 2. Consider a usage of millions of users consuming the ESB service at a given time. Could OPS or ODS handle these incoming requests at the same rate, the ESB accepts them from the users ?

观察图 1 与图 2 中的例子。考虑在某个时间段内使用 ESB 服务的数百万用户的使用情况。OPS 或 ODS 能够以相同的速度处理这些 ESB 接收到的用户请求吗?

As discussed earlier an ESB is commonly seen as a backbone in an enterprise, which means it should be able to handle high amount of request load. Request load is commonly measured in Transactions Per Second (TPS). The services implemented in the organization (OPS or ODS) might not be designed to handle requests at the same TPS rate as the ESB. As a matter of fact what could go wrong? As explained in [6] a service or a system could fail to deliver due to presence of faults or the system being overloaded. If the ESB routes the requests to OPS or ODS at the same TPS rate it receives the requests and if the services cannot withstand that rate these service would be overloaded and would fail to deliver the responses. Failure in the service would result in losing the request message the ESB accepted from the user.

如前所述,ESB 通常被视为企业中的主干,这就意味着它应能够处理高数量的请求负载。请求负载通常以每秒事务数(下文简称 TPS,Transactions Per Second)进行度量。在机构中实现的服务(OPS 或 ODS)可能不会被设计为能与 ESB 相同的 TPS 速率来处理请求。实际上,那会有什么问题呢?正如 [6] 中所述,由于出现故障或系统过载,服务或系统可能无法完成交付。如果 ESB 以相同的 TPS 速率将请求路由到 OPS 或 ODS,此时若服务不能承受该速率,那么这些服务将超载,并且无法交付响应。服务中的错误将会导致 ESB 从用户端接收到的请求被丢失。

Therefore, it is essential to take proactive measures to prevent the services from being overloaded, in order to ensure that the system does not crash measures should be taken to ensure the communication link is much more reliable (zero message loss), so that if the ESB accepts a request from the user, the ESB should guarantee the delivery (reliability) of the message among all the services.

因此,采取积极主动的措施防止服务过载是至关重要的,为确保系统不会崩溃,我们应采取应对措施保证通信链路是更加可靠的(无消息丢失),所以若 ESB 接收了来自用户的请求,它应确保所有服务之间的信息能够交付(可靠性)。

Next section would focus on how communication links between the ESB could be made reliable and measures which could be taken to prevent the services (OPS and ODS) from being overloaded.

下一节我们将聚焦于如何使 ESB 之间的通信链路能够可靠地进行,并采取应对措施防止服务(OPS 和 ODS)过载。

Reliable Communication

(可靠通信)

One of the traditional ways of achieving reliable communication was to use WS-ReliableMessaging. However, this evolved with the growth of Restful APIs [1] since WS-ReliableMessaging is specific to Web Services. Also Marc in [7] argues how reliability should be taken out from the transport layer and the necessity of including it with the business semantics. However, in my opinion this approach would be applicable only if all the services in the system are implemented in-house. this would not be the case for most of the enterprises; one of the main purposes of moving to SOA is to make the system extensible so that it could re-use and interoperate between services which are implemented in-house and/or exposed by third party service/API vendors. Since, an organization cannot influence the external service vendors to adhere to specific business semantics, reliability should not be tightly coupled to the business application level. Therefore, it would be essential to use a more generic (independent of its business semantics) mechanism to achieve reliability of system.

实现可靠通信的一个传统的方法是使用 WS-ReliableMessaging(可靠消息传输,这是一种数据传输协议)。然而,随着 Restful api [1] 的发展,这一方法也随之发展起来,因为 WS-ReliableMessaging 是特定于 Web 服务的。在文章 [7] 中,Marc 还讨论了如何从传输层中提取可靠性,以及是否有必要将其与业务语义(Business semantic)结合起来。然而,依我看,只有当系统中的所有服务都是在内部实现时,这种方法才能适用。对于大多数企业来说,并非是内部实现的情况。迁移到 SOA 的一个主要目的是使得系统具有可扩展性,以便在内部实现的服务和(或者)第三方服务(或 API 供应商)公开的服务之间能够重用以及互用。由于组织机构不能影响外部服务供应商遵守特定的业务语义,因此可靠性不应该与业务应用级别紧密耦合。因此采用一个更通用(取决于它们的业务语义)的机制来实现系统可靠性是必须的。

Message-Broker is an intermediary pattern which decouples message senders and receivers. Most of the ESB vendors support integrating with Message Brokers (MB) via protocols such as JMS. The next sections would focus on elaborating how ESB and MB patterns together could be used to achieve a more reliable communication link between the services which are chained through the ESB (achieve zero message lost). Also would elaborate how MB would come into play to offer means to control the TPS rate (throttle) in which the messages are routed through the ESB to the services (OPS and ODS), to prevent the services from being overloaded.

Message-Broker(消息中介)是一种中介模式,它能解除消息发送方与接收方之间的耦合。大多数 ESB 供应商都支持对消息代理(下文简称 MB,Message Broker)的集成(通过诸如 JMS 这样的协议实现)。下一节将重点讨论如何将 ESB 和 MB 模式组合在一起,从而在通过 ESB 链接的服务之间实现更可靠的通信链路(即实现零消息丢失)。同时也会详细说明 MB 将如何发挥作用,以提供控制消息通过 ESB 路由到服务(OPS 与 ODS)时的 TPS 速率的方法(即节流),以防止服务过载。

Request Rate Control

(请求速率控制)

Message Brokers (MB) revolves around several messaging concepts. Mainly based on queues (point to point) and topics (pub/sub). These concepts are designed to decouple between time and space [8]. So that if a given message is inserted into the queue by the sender the broker will ensure to deliver the message to it’s receiver. If the receiver is unavailable at the time the message was sent, the broker will persist the message until the receiver becomes available. Let’s take a look at how MB could be intercepted with the ESB for the same pizza delivery system example which was discussed earlier. The intention is to illustrate how the MB could be added without creating an adverse effect on the services (OPS and ODS) as shown in Figure 3 and Figure 4.

MB 围绕着几个消息传递概念。主要基于队列(点对点)与主题(发布/订阅)。这些概念的设计是为了解开时间和空间之间耦合 [8]。因此,如果发送方将给定的消息插入到队列中,代理者将确保将消息传递给它的接收方。若接收方在消息发送时是不可用的,代理将保有消息直到接收方的状态变为可用为止。让我们回顾之前的披萨外卖系统例子,在这个情景下 ESB 是如何截取 MB 的。我们的目的是说明如何添加 MB 而不会对服务(OPS 和 ODS)造成负面影响,如图 3 和图 4 所示。

图3. 通过 ESB 存储与转发

图4. 存储与转发消息流

As depicted in the above message flow diagram (figure 4),

  • The client sends the order message to the ESB.
  • The ESB accepts the incoming HTTP message and re-publish the message to a queue (OPSQ) in message broker via a brokering API (JMS).
  • The stored message is consumed from OPSQ by the ESB at a controlled rate. (i.e once in every 30 seconds). The broker deletes the message from the queue once consumed.
  • The consumed message is sent to OPS by the ESB through performing a protocol conversion between JMS to HTTP.
  • Once OPS responds, the response message is published by the ESB to ‘ODSQ’ queue.
  • The same procedure described in steps 3 and 4 would imply to deliver the message to ODS at a controlled rate.

正如上面的消息流简图(图 4)所示:

  1. 客户端发送订单信息到 ESB。
  2. ESB 接收 HTTP 消息,并通过代理 API (JMS)重发布消息到 MB 的一个队列中(OPSQ)。
  3. 存储的消息由 ESB 以可控的速度从 OPSQ 中消费出去(比如每三十秒一次)。一旦消息被消费,则相应地代理者会从队列中将其删除。
  4. 被消费的消息由 ESB 发送到 OPS 中(通过执行 JMS 到 HTTP 的协议转换)。
  5. 当 OPS 作出响应时,响应消息有 ESB 发布到 ODSQ 队列中。
  6. 此时经过与 3、4 步骤相同的动作,则消息就以可控的速率被传递到 ODS 中。

Let’s take a look at the following benefits and drawbacks of using message broker,

Benefits:

  • The approach could be used with any service implementation i.e Web Service, Restful.
    -Messages would be persisted in the queue or the topic if the services cannot withstand the incoming TPS rate. This would ensure to achieve guaranteed delivery of messages as well as the services could consume messages at a controlled TPS rate.
  • Message broker could be added without creating an adverse impact on the service implementation (OPS and ODS). Hence this approach becomes much more agile when integrating with 3rd party APIs and achieve reliability.

Drawbacks:

  • Addition of broker means an extra layer the message will go through. This is apparent when referring to the figures 2 and 4. When the broker was added the message will now go through 2 extra layers (OPSQ and ODSQ).

现在我们看看使用 MB 的优点与缺点。

优点:

  • 该方法适用于任何服务的实现,例如 Web 服务以及 Restful。
  • 如果服务无法承受传入的 TPS 速率,消息将被保持在队列或主题中。这将确保实现消息的保证交付,并且服务可以以控制的 TPS 速率使用消息。
  • 加入 MB 时,不会对服务实现(OPS 和 ODS)产生负面影响。因此,当与第三方 API 集成并实现可靠性时,这种方法更加敏捷。

缺点:

  • 添加代理意味着消息会经过一个额外的层。参阅图 2 与图 4,这一点就非常明显了。当代理被加入时,消息会经过两个额外的层(OPSQ 与 ODSQ)。

The more layers the message goes through (network hops) the more latency it would add for the client to receive the response [9]. Besides if the services which were chained (OPS and ODS) consumed at a lower TPS rate (throttled). The impact on the response latency for the client would be higher.

消息经过的层数(网络跃点)越多,它将为客户端带来更高的延迟以接收响应 [9]。此外,如果服务是以较低的TPS速率(节流)消费,则对客户端响应延迟的影响会更高。

The next section would focus on elaborating how increase in the response latency could have an adverse effect on the client.

下一节我们将重点阐明响应延迟的增加如何会对客户端产生不利影响。

Adverse Effects of Response Latency

(响应延迟的副作用)

Depending on the Operating System (OS), the client keep-alive timeout could vary between ~20-75 seconds. For the above example if the sender (client) block waits to receive a response from the proxy service (synchronously), the proxy service is expected to deliver a response to the client in less than 20 seconds. Else the sender would timeout and would assume the transaction had failed, but it may have not. The message would’ve being processed by all the services (OPS,ODS) even though the sender was not notified on time. As a result assuming the transaction has failed the sender will re attempt to send the same message again which causes inconsistencies.

依据所使用的操作系统(简称 OS,Operating System),客户端保持连接的超时时间大概在 20 秒到 75 秒之间变化。对于上述例子,若发送方(客户端)阻塞等待以接收从代理服务发送来的响应(即以同步的方式),则代理服务需要在 20 秒内向客户端发送响应。否则发送方将会超时,并认定事务失败了(但它可能并没有失败)。及时发送方未及时进行通知,消息也会被所有服务(OPS 以及 ODS)进行处理。因此,假设事务失败,发送方将再次尝试发送相同的消息,这将会导致不一致。

Measures should be taken to prevent these inconsistencies. The reality is systems should not assume it could always deliver the message to the caller/sender before it times out, since response time could be subjective, especially when services consume the messages at a controlled rate and when there’re multiple network hops the message would go through to achieve reliability goals. Therefore, it would be of best interest for the sender to move away from synchronous (blocking) way of communication to asynchronous (non-blocking).

我们需要采取一些应对措施来避免这些不一致。现实情况是,系统不应假定它总是能在超时之前将消息传递给调用者或发送方,因为响应时间可能是主观的,特别是当服务以控制的速度使用消息,并且消息需要通过多个网络跳变实现可靠性时。因此对于发送方来说,从同步(阻塞)通信方式转变为异步(非阻塞)通信方式是最有利的。

Asynchronous Communication

(异步通信)

There are pros and cons of using asynchronous communication when compared against RPC based synchronous communication [9]. As elaborated in [9], as opposed to synchronous communication, asynchronous communication will keep the sender blocked only for a less amount of time.

对比起基于 RPC 的同步通信,使用异步通信有优点亦有缺点 [9]。正如文章 [9] 中所阐述的那样,与同步通信不同,异步通信只会使发送方在更短的时间内被阻塞。

Referring to the example elaborated in figure 4, Instead of having the ESB respond to the client after calling each service i.e OPS and ODS, we could have the ESB respond to the client immediately after publishing the message to the message broker. This approach will reduced the response latency for the sender. However, there are a few gray areas which needs to be addressed.

  • How will the sender be notified if an error occurs when the message is being processed through the services (OPS,ODS) ? or an update on the status of the order delivery ?
  • As described in [9], unlike synchronous communication, asynchronous communication by default does not provide guarantees to the sender on successful delivery of the message at the destination. In that case how could the sender be assured on successful processing of the order which was placed.

参考图 4 中的例子,我们可以在消息发布到消息代理之后直接让 ESB 给客户端响应,而不是在调用每个服务(如 OPS 与 ODS)之后再响应。这种方法将会给发送方缩短响应延迟。然而,这其中有些许灰色地带需要我们解决。

  1. 当消息正被服务(OPS,ODS)处理时,若发生了一个错误,发送方要如何收到通知?或者说订单状态要如何更新?
  2. 如文章 [9] 中描述,异步通信不像同步通信那样,默认情况下,它对于发送方并不提供将信息成功交付到目的地的保证。在这种情形下,发送方要如何保证成功地处理所下的订单?

The next sections would describe how the above areas could be addressed.

下一节中,将会介绍以上两种情况要如何去解决。

Linked Services Pattern

(链接服务模式)

Linked Service [10] is a service design pattern which defines a mechanism for senders/clients to discover related services which could be used to identify the status of the request which is being processed. The pattern basically specifies to include hyperlinks in the response message delivered to the sender, so that the sender could later refer to these links to track the status of the request. Along with adapting to asynchronous communication, service owners could provide hyperlinks to the service callers (senders) in the response message. This way the sender could use these links to identify the status of the order delivery or any error condition which may have occurred when the the message is being processed.

链接服务 [10] 是一种服务设计模式,它为发送方/客户端定义了一种机制,以发现能够确定正在被处理的请求状态的相关服务。这种模式主要指定在给发送方的响应消息中包含超链接,以便发送方以后可以引用这些链接来跟踪请求的状态。除了适应异步通信之外,服务所有者还可以在响应消息中为服务调用者(发送方)提供超链接。按照这种方法,发送方可以使用这些链接来确定订单交付的状态,或者在处理消息时可能发生的任何错误情况。

Illustrated below is how the sender could communicate with the services asynchronously using linked services pattern.

下图展示了发送方如何能够与服务异步地通信(使用链接服务模式)。

图5. 异步消息

As depicted in the figure 5,

  • The client sends the order message to the ESB.
  • The ESB accepts the incoming HTTP message and re-publish the message to a queue (OPSQ) in message broker via a brokering API i.e JMS.
  • Once the message is published to the queue, the ESB responds back to the client. The response includes a hyperlink which allows the client to refer and track the status of the order.
  • From thereon, the message flow is similar to step 3-6 described in section 1.

如图 5 所示:

  1. 客户端发送订单消息到 ESB。
  2. ESB 接收 HTTP 消息并且通过代理 API(如 JMS)重发布消息到 MB 的一个队列(OPSQ)中。
  3. 一旦消息发布到队列中,ESB 就给客户端发送响应。这一响应包含了一个超链接,它允许客户端引用并追踪订单状态。
  4. 在此基础上,消息流类似于第 1 节中描述的步骤 3-6。

Delivery Guarantees and Transactions

(交付担保以及事务)

When messages are sent without expecting acknowledgments (fire-and-forget pattern) there’s a risk of losing the message, because there is a chance that the network or system that the message is sent could be erroneous or unreliable. What will happen if the JMS message published to the broker (OPSQ) by the ESB doesn’t reach the queue?

发送消息时不需要确认(即发即弃模式)时,会有消息丢失的风险,因为发送消息的网络或系统有可能是错误的或不可靠的。若通过 ESB 向代理(OPSQ)发布的 JMS 消息没有到达队列,此时会出现什么问题呢?

Since the sender would be informed on successful acceptance of the message after placing the message on the queue. it would be essential to verify with the MB whether the message was successfully placed into the queue, before sending the acceptance response to the sender. Also it would be essential to always verify whether the recipients who consume the message from the queue successfully consumes it before deleting it from the queue.

由于发送方会在将消息放置到队列后成功接收消息时被通知,在向发送方发送接收响应之前,必须同 MB 验证消息是否已成功地放入队列。并且,在删除队列消息之前,总是确认(Acknowledgement)其被接收方成功地消费是必要的。

MB will send a publisher acknowledgment to the callers when it successfully accepts a message to the queue and will delete a message from the queue when an acknowledgement is being sent by the consumer who receives it. By default in JMS [11] the acknowledgment mode is AUTO_ACKNOWLEDGE, where the consumer (ESB) would acknowledge the message upon receiving it.

当 MB 成功地接收消息到队列时,它会向调用者发送一个发布者确认消息,当接收到该消息的消费者发送一个确认消息时,MB 将从队列中删除一条消息。JMS 在默认情况下 [11],确认模式是 AUTO_ACKNOWLEDGE,则当消费者(ESB)接收到消息时会对其进行确认。

The potential risk which would affect the pizza delivery system would be, to have OPS return an error status or not returning a response at all after consuming the message from the queue. Since the ESB by default would AUTO_ACKNOWLEDGE to OPSQ the message would be discarded from the queue immediately after it’s consumed by the ESB. The whole idea is to make sure OPS and ODS successfully receives the message, acceptance of the message by the ESB would not guarantee to deliver the message to the relevant services (OPS,ODS).

会影响披萨外卖系统的潜在风险是,在从队列中消费了一个消息后,OPS 返回一个错误状态,或者完全无响应。由于 ESB 默认情况下将 OPSQ 设置为 AUTO_ACKNOWLEDGE 模式,因此消息在被 ESB 消费后将立即从队列中丢弃。整个想法是确保 OPS 和 ODS 能成功地接收到消息,ESB 接收消息并不会保证将消息传递给相关的服务(OPS、ODS)。

JMS, CLIENT_ ACKNOWLEDGEMENT mode would be an option which could be used. This mode allows the consumer explicitly acknowledge or rollback the message instead of auto acknowledging the message upon receiving it. This way if there is an error thrown from OPS or ODS services, the consumer (ESB) could rollback the message and have the message replayed until it is delivered. The MB would ensure to persist the message until its being acknowledged by the ESB. More information on acknowledgment modes could be found in [12].

JMS 中,可以使用的一个选项是 CLIENT_ ACKNOWLEDGEMENT 模式。这个模式允许消费者显式地进行确认或回滚消息,而不是当接收到消息时自动确认。通过这种方式,如果 OS 或 ODS 服务抛出错误,则使用者(ESB)可以回滚消息并重放消息,直到消息被传递。MB 则会确保消息被保留到 ESB 确认它为止。关于确认模式的更多详细信息可以参考文章 [12]

图6. 消息流

As depicted in figure 6,

-The client sends the order message to the ESB.
- The ESB accepts the incoming HTTP message and re-publish the message to a queue (OPSQ) in message broker via a brokering API i.e JMS.
- ESB waits for the broker to acknowledge on accepting the message to OPSQ. (publisher acknowledgment)
- Once acknowledged the ESB sends the confirmation response to the client.
- ESB peeks the message from queue using CLIENT_ACKNOWLEDGE mode. (This ensures that the message would not be discarded from OPSQ until the client sends an acknowledgement or rejection)
- ESB dispatches the request to OPS. If OPS sends a successful response, the ESB acknowledges the message and inform OPSQ to delete the message from the queue. If the status is an error, the ESB sends a rejection to OPSQ asking it to rollback, so that the message will not be discarded but rather be ready to consume again (replayed).
- The same steps will be applicable when sending a message to ODS by consuming from ODSQ.

如图 6 所示:

  1. 客户端发送订单消息给 ESB。
  2. ESB 接收 HTTP 消息,并通过一种代理 API(如 JMS)重发布该消息到 MB 的一个队列(OPSQ)中。
  3. ESB 等待代理确认接收到消息并已经将其加入 OPSQ 中。
  4. 一旦得到确认,ESB 就发送确认响应(Confirmation response)给客户端。
  5. ESB 使用 CLIENT_ACKNOWLEDGE 模式从队列中查找消息。(这就确保消息不会被丢弃直至客户端发送一个确认或拒绝消息)
  6. ESB 将请求发送到 OPS。若 OPS 发送一个成功响应,则 ESB 确认该消息并通知 OPSQ 从队列中删除消息。如果状态为错误,则 ESB 发送一个拒绝消息到 OPSQ,告知它需要进行回滚,使得消息不会被丢弃,而是准备再次使用(重播)。
  7. 当从 ODSQ 中进行消费而发送一个消息到 ODS 时,以上步骤同样适用。

Conclusion

(总结)

In conclusion, patterns such as ESB brings great benefits when integrating between heterogeneous services. However, ESB alone does not address all the integration challenges which a system would face. The services orchestrated/chained through the ESB might not be able to handle the incoming requests at the same TPS rate the ESB accept the requests from the users. Due to this the services could be overloaded, resulting the systems to crash and fail to deliver. Message Brokers could be used to control the rate on which the services consume messages, ensuring reliability. Also using Message Brokers would not have any adverse effect on the implementation of the services, making it suitable to ensure reliability for both in-house and 3rd party services/APIs. While using Message Brokers to achieve reliability and to rate control between the services there will be a proportional impact on the response latency. Increase in response latency would create inconsistencies due to client time-outs. Therefore, it would be beneficial to consider asynchronous communication over synchronous, to avoid these inconsistencies. Asynchronous communication would have a lesser response latency in comparison synchronous, however unlike synchronous communication it does not implicitly provide a way for the caller to identify the state of the request which is processed as well as does not implicitly guarantee delivery of the message. These gaps could be fulfilled by explicitly using service design patterns such as LinkedServices and proper acknowledgment modes.

总的来说,诸如 ESB 这样的模式在集成异构服务时能给我们带来很多好处。然而仅仅采用 ESB 无法解决系统面临的所有集成挑战。通过 ESB 进行编排/链接的服务,它们处理输入的请求的 TPS 速率可能无法与 ESB 从用户端接收请求的速率等同。这就导致服务可能会过载,于是系统会崩溃并且交付失败。消息代理(MB)可以用于控制服务消费消息的速率,从而确保可靠性。同时,使用 MB 不会对服务的实现造成任何负面影响,因此它适合于确保内部和第三方服务/API 的可靠性。在使用 MB 实现可靠性并控制服务间的速率时,会对响应延迟产生成比例的影响。响应延迟的增加会造成不一致(由于客户端会超时)。因此,为避免这些不一致,考虑使用异步通信比用同步通信有更多优势。对比同步通信,异步通信能使响应延迟变低,然而与同步通信不同的是,它不会隐式地为调用者提供一种方式来识别被处理的请求的状态,也不隐式地保证消息的传递。我们可以通过显式地使用服务设计模式(例如链接服务模式与适当的确认模式)来弥补这些缺口。

猜你喜欢

转载自blog.csdn.net/qq_16775897/article/details/81008747