[微服務技術文章之其一] 服務整合時需避免的兩個錯誤

StoneDemo發表於2018-07-11

日常前言

  • 翻譯任務終了,最近的專案也已經交付出去,現在剩下的就是一些歷史遺留問題要慢慢和第三方溝通處理……開始進入真正的專案空閒期了。不過大概再有兩個星期,就又要開始搞新的機型了,這次還是用的高通 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 實現可靠性並控制服務間的速率時,會對響應延遲產生成比例的影響。響應延遲的增加會造成不一致(由於客戶端會超時)。因此,為避免這些不一致,考慮使用非同步通訊比用同步通訊有更多優勢。對比同步通訊,非同步通訊能使響應延遲變低,然而與同步通訊不同的是,它不會隱式地為呼叫者提供一種方式來識別被處理的請求的狀態,也不隱式地保證訊息的傳遞。我們可以通過顯式地使用服務設計模式(例如連結服務模式與適當的確認模式)來彌補這些缺口。

相關文章