1. 程式人生 > >原理解析Service Mesh與ESB、API管理與訊息代理的關係

原理解析Service Mesh與ESB、API管理與訊息代理的關係

轉載自公眾號 EAWorld。

作者:Christian Posta
譯者:海松
原題:Application Network Functions With ESBs, API Management, and Now.. Service Mesh?

最近我談到了微服務模式的發展①,以及像service proxies like Envoy from Lyft②的文章,闡述服務代理如何將彈性、服務發現、路由、指標收集等職責推到應用程式下層。否則,我們只能寄希望於各種應用程式自己能正確實施這些關鍵功能,或依賴某個特定語言的庫來實現這點。有趣的是,這種service mesh的思路與我們的企業領域客戶熟悉的其他概念有關。我收到了很多關於這種關係的問題。具體來說,service mesh與ESB、訊息代理和API Management的關係是什麼?這些概念肯定有重疊,所以讓我們來深挖一下。關注Twitter @christianposta瞭解更多資訊!

一、四個假設

● 服務通過網路進行通訊

第一點:我們談的服務是通過非同步、包交換(packet-switched)網路進行通訊和互動的服務。這意味著它們在自己的程序中執行,並且在自己的“時間邊界”內(time boundaries,此處即非同步的概念)中執行,且通過在網路中傳送包進行通訊。不幸的是,沒有任何東西可以保證非同步網路互動③:我們最終可能會遇到互動失敗、互動停滯/延遲等等,而且這些情況不好區分。
這裡寫圖片描述

● 如果仔細觀察,這些互動並非微不足道

第二點:這些服務如何互相互動並非微不足道。我們必須處理以下事情,比如故障/部分成功、重試、重複檢測、序列化/反序列化、語義/格式轉換、多語言協議、路由到正確的服務來處理訊息、處理訊息洪泛(floods of messages)、服務編排、安全性影響等等。而其中許多事情可能而且必定會出錯。

● 瞭解網路非常重要

第三點:瞭解應用程式如何通訊、訊息如何交換以及如何控制流量非常重要。這點非常類似於我們如何看待第3/4層網路。瞭解以下內容是有價值的,如:哪些TCP段和IP資料包正穿過網路、控制路由它們和允許它們的規則等等。
這裡寫圖片描述

● 最終責任在應用程式

最後:正如通過端到端的論證④證我們所知道的,應用程式本身應當負責其業務邏輯的安全性,保證正確的語義實現。無論底層基礎設施(即使會遇到重試、交易、重複檢測等等)的可靠性如何,我們的應用程式必須防範使用者做出糊塗的行為(如同一命令重複提交)。提供實現或優化的細節能有助於幫助實現。但不幸的是,沒有辦法解決這個問題。

二、應用程式網路功能

我認為,無論你更傾向於哪個服務架構(微服務、SOA、物件請求代理、客戶端/伺服器等),以上要點都是有效的。然而,過去我們對於哪些優化屬於哪裡十分模糊。在我看來,不僅橫向的應用程式網路功能可以從應用程式中被優化掉(然後被投入到基礎設施中 - 就像我們在較低級別堆疊上所做的事情那樣),而且還有其他應用程式網路功能與我們的業務邏輯更密切相關,但卻不應該被輕易地“優化”(optimized)掉。

三、網路

讓我們迅速回顧下應用程式之下的網路是什麼樣的,它可是地位超凡哦:)。當我們從一個服務發“訊息”到另一個服務時,我們將其傳遞到了作業系統的網路堆疊,作業系統會嘗試將這條訊息放入網路中。根據網路所處級別,網路會處理傳輸單元(幀、資料報、資料包)等。這些傳輸單元通常包括一個由“資料頭”和“有效負載”組成的結構,“資料頭”包含關於傳輸單元的元資料。通過元資料,我們可以做很多基礎的事情,例如路由、確認跟蹤/去重等。
這裡寫圖片描述

這些傳輸單元通過網路中的不同點進行傳送,這些點決定了是否允許單元通過,是否將其路由到不同的網路,或將其傳送到預期的接收者處。在路徑上的任意一點,這些傳輸單元可能被丟棄、複製、重新排序或推遲。更高階的“可靠性”功能,如作業系統內網路堆疊中的TCP,則可以跟蹤重複、確認、超時、排序、丟失的單元等東西,並可以進行故障重試、資料包重新排序等。
這裡寫圖片描述

這類功能由基礎設施提供,不與業務邏輯混合 – 而且其規模相當可觀,達到了網際網路規模! 我剛看到的Phil Calcado精彩的部落格很好地解釋了這點⑤。

四、應用程式

在應用程式級別上,我們在做類似的事情。我們將與協作者服務的對話拆分成包含“訊息”(請求、事件等)的傳輸單元。當我們通過網路進行呼叫時,我們必須能為應用程式訊息執行超時、重試、確認、應用背壓(apply backpressure)等操作。這些都是應用程式級別普遍的問題,並且在構建服務架構時總會出現。我們需要解決它們。我們需要一種實現應用網路功能的方法。
這裡寫圖片描述

例如:過去我們嘗試用郵件代理解決它們。有一組集中的面向訊息的中介軟體(甚至可以通過多協議支援,使我們可以轉換訊息的有效負載,“整合”多個客戶端),它們負責在客戶端之間傳遞訊息。我看到的很多例子使用的模式基本上是通過訊息系統進行請求或回覆(RPC)。
這裡寫圖片描述

這間接幫助解決了應用程式網路功能中的一些問題。負載均衡、服務發現、背壓、重試等工作都被委託給了訊息代理。由於所有流量都要經過這些代理,所以我們有了一箇中心點,從這個中心點可以觀察和控制網路流量。但是,正如@tef_ebooks在Twitter⑥上指出的那樣,這種做法用力過度,有些矯枉過正了。它往往會成為架構的瓶頸,用它來進行流量控制、路由、策略執行等並不像我們想象那麼容易。

所以我們也做過同樣的嘗試。我們覺得“好吧,就把路由、轉換、策略控制”加到現有的集中式訊息匯流排裡吧。實際上這是個非常自然的演變。我們可以使用訊息主幹網(messaging backbone)來提供集中化、控制和應用程式網路功能,如服務發現、負載均衡、重試等等,但還要加入更多內容,比如協議調解、訊息轉換、訊息路由、編排等功能,因為我們覺得如果可以將這些看似同一層面的內容加入到基礎設施中,應用程式或許會更輕量、更精簡、更敏捷等等。這些需求絕對是真實的,ESB演變並滿足了這些需要。
這裡寫圖片描述

正如我的同事Wolfram Richter⑦指出,“關於ESB概念,IBM關於SOA架構的2005年白皮書(http://signallake.com/innovation/soaNov05.pdf第2.3.1章)提供瞭如下的定義:

在SOA邏輯架構中,企業服務匯流排(ESB)是名安靜的夥伴。它在體系結構中的存在對於SOA應用程式的服務來說幾乎是透明的。然而,ESB的存在是簡化服務呼叫的基礎,使我們能隨時隨地呼叫服務,而無需定位服務或是上傳服務請求這些細節。

這似乎是行得通的!甚至像我們正在嘗試的新技術一樣。知道嗎?我們的確是在嘗試新技術!!!之前的問題並未奇蹟般地消失,只是背景和環境發生了變化。我們希望從過去未達成的目標中吸取經驗。

例如,在大型供應商展望的SOA時代(通過委員會等方式編寫無窮盡的規範、重新命名EAI等),我們發現三件事導致了“ESB”的承諾未能實現:

• 組織結構(讓我們不停地建造一個個豎井(silo)!)
• 技術複雜(SOAP/WS- *、JBI、規範XML、專有格式等)
• 需要業務邏輯來實現路由、轉換、中介、編排等

而最後一點導致了過度操作。我們希望敏捷化,但我們將重要的業務邏輯從服務中分離出來,並轉移到另一個團隊擁有的整合層。現在,當我們想要更改服務時(出於敏捷的需要),我們做不到;我們不得不暫停並和ESB團隊產生大量同步(這會帶來風險)。隨著這個團隊和這個架構成為應用程式的中心,我們就可以理解ESB團隊為什麼會被請求所淹沒(同樣是因為敏捷的需要),無法跟上節奏了(即風險的體現)。所以儘管意圖很好,但是我們發現把核心的應用程式聯網功能與業務邏輯有關的功能混到一起不是個好主意。我們最終會遭遇瓶頸。
這裡寫圖片描述

接下來出現的是REST革命和API優先的思潮。這一運動部分是出於對SOAP/ESB/SOA複雜性的抵制,部分是考慮通過API轉換資料,引發新的商業模式,擴充套件現有模式。我們還向架構引入了新的基礎設施:API管理閘道器。該閘道器讓我們能集中地控制針對業務API的外部訪問,它是通過安全ACL、訪問配額和API使用計劃、指標收集、計費、文件等實現的。然而,就像我們在前面的訊息代理例子中看到的那樣,當採用集中治理時,我們會有一次處理過多事情的風險。例如,我們會想,當API呼叫通過我們的閘道器時,為何不新增路由、轉換和編排呢?然而,這樣做的後果是我們開始妄想打造一個能夠將基礎設施級網路問題與業務邏輯相結合的ESB。這是一條死衚衕。
這裡寫圖片描述

但是,即使在REST/非SOAP時代,我們仍需要解決上述各項服務之間的問題,(不僅僅是所謂的“南北”流量(編者注:“North-South” traffic。網路傳輸的流量方向,南北一般指代縱向的不同層級間的傳輸流量,比如內外網,東西一般指代同一級別的傳輸流量,比如虛擬機器之間),還包括“東西方”流量互動的問題)。更具挑戰性的是,我們需要找出一種使用商用基礎設施環境(又名雲)的方法,而這種方法往往會加劇上述問題。傳統資訊代理、ESB等不適合這種模式。相反,我們最終會在業務邏輯中編寫應用程式網路功能。……我們開始看到諸如Netflix OSS堆疊⑧、Twitter Finagle⑨這樣的事物,甚至還有我們自己的Fuse Fabric,它們的確可以解決其中的一些問題。它們通常是庫或框架,旨在解決上述一些問題,但它們是特定語言編寫的,並且混合在業務邏輯中(或在整個基礎設施中分散的業務邏輯中)。因此,這個模式也有問題。這種方法需要在每種語言/框架/執行環境上進行大量投資。我們基本上必須在跨語言/框架上加倍努力,並期望它們能夠有效、正確和一致地工作。
這裡寫圖片描述

經歷了上述這些困難,在有能力控制/配置/監控應用級請求的前提下,我們能用最低的成本,高度分散(high decentralization)地將應用網路功能加入到基礎設施中,從而解決上述的一些問題。我們稱之為“service mesh”。基於Envoy Proxy⑩的istio.io⑪就是個很好的例子。它使我們將應用程式網路功能的問題與業務邏輯區分的問題分離開來:
這裡寫圖片描述

正如Phil Calcado說的那樣⑫,這與TCP/IP網路層的工作非常相似;網路功能被推入到作業系統中,但它們並不是應用程式的一部分。

五、與此相關的概念

通過service mesh,我們明確地將應用程式網路功能與應用程式程式碼、業務邏輯分離開來,我們正在將其推向另一個層次(推向基礎設施,這與我們在網路堆疊、TCP等方面所做的工作類似 )。
這裡寫圖片描述

所涉及的網路功能包括:

• 簡單的、基於元資料的路由
• 自適應/客戶端側負載均衡
• 服務發現
• 熔斷
• 超時/重試/預算
• 速率限制
• 度量/記錄/追蹤
• 故障注入
• A/B測試/流量整形/請求映象

明確不含以下專案(這些專案可能更適合於業務層級的邏輯、應用程式和服務,而不是某些集中式基礎設施。):

• 訊息轉換
• 訊息路由(基於內容的路由)
• 服務編排

那麼service mesh與以下事物的不同點在於

ESB

• 在某些網路功能上有重疊
• 控制點分散
• 策略針對特定應用程式
• 不處理業務邏輯問題(如對映、轉換、基於內容的路由等)

訊息代理

• 在服務發現、負載均衡、重試、背壓等方面有重疊(大概差著30,000英尺)
• 控制點分散
• 策略針對特定應用程式
• 不承擔發訊息的職責

API管理

• 在策略控制、速率限制、ACL,配額安全等方面有重疊
• 不處理API的業務方面(定價、文件、使用者到計劃的對映等)
• 類似點在於它不實現業務邏輯

至於API管理,似乎有一些重疊,但我更傾向於把這些重疊看作是高度互補。API管理提供有關API的更高階語義(如文件、使用者註冊/訪問、生命週期管理、開發人員API計劃、計費和退款等)。呼叫API時,較低級別的應用程式網路,如熔斷器、超時、重試等都是至關重要的,但它們很適合service mesh層。重疊點如ACL、速率限制、配額和策略執行等可以由API管理層定義,但實際上由service mesh層實施。通過這種方式,我們可以擁有完整的端到端策略和訪問控制,並強化南/北流量和東/西流量的彈性。如@ZackButcher⑬(來自Istio團隊)在twitter中⑭指出那樣,“隨著規模越來越大,從生產和管理服務的角度來看,東西流量開始變得更像南北流量。”
這裡寫圖片描述

六、把它們都整合起來

這裡寫圖片描述

我們需要採用API優先的方法來處理我們的系統架構。我們也要解決彈性等問題。我們也發現了在整合上的挑戰。在許多方面,將基於非同步事件傳遞和事件處理的架構作為您的API和微服務互動的底層可以幫助提高可用性、彈性和降低脆性。過去,解決這些問題是一項挑戰,因為競爭產品和解決方案的關注存在重疊和混淆。隨著我們轉向雲架構,這種情況變得越來越明顯,我們需要梳理這些問題,並將它們放在我們的架構中的適當位置,否則我們就會重蹈覆轍。

從上圖可以看出:

• API管理用於進入的南/北流量
• service mesh(控制+資料層)用於服務之間的應用網路功能
• service mesh執行東西流量的API管理策略
• 整合(編排、轉換、反損壞(anti-corruption)層)作為應用程式的一部分
• 事件驅動的訊息底層(back plane),用於真正的非同步/事件驅動的互動

如果我們回顧前面提到的四個假設,那麼下面是我們如何解決它們的方法:

• 第一:服務通過網路進行互動 –我們使用service mesh資料層/服務代理
• 第二:互動並非微不足道的 –在業務本身實現業務整合
• 第三:控制和可觀察性 –使用API管理加service mesh控制層
• 第四:您具體的業務邏輯;使用service mesh/訊息傳遞等進行優化

七、業務邏輯真的可以被分離出來嗎?

我想是可以的,但會存在不清晰的邊界。在service mesh中,我們說應用程式應該能意識到應用程式網路功能,但是不應該在應用程式程式碼中被實現。如何使應用程式更清楚地意識到應用程式網路功能或service mesh層正在做什麼事情,有待進一步說明。我認為在這種情況下,很多庫或框架會被創建出來。例如,如果Istio service mesh觸發熔斷,重試一些請求,或者由於特定原因而失敗,那麼應用程式需要對這些場景有更多的上下文資訊以供理解。我們需要一種方法來捕獲這些情況或背景並將其反饋給服務。另一個例子是在服務之間傳播跟蹤背景(即分散式跟蹤,如OpenTracing),並且透明地完成傳播。我們或許會看到,這些輕型的應用程式/特定語言的庫可以使應用程式/服務更智慧,並允許它們追溯特定的錯誤。

八、我們該何去何從

今天這一架構的所有部分具有不同的成熟度。即使如此,對我們的服務架構採取原則化的方法是關鍵。業務邏輯與應用程式網路應該分開。使用service mesh實現應用程式網路,使用API管理層來處理高級別的以API為中心的問題,將讓特定業務的整合放在服務層中。這樣一來,我們就可以通過事件驅動的底層(backplane)構建資料密集型或資料可用系統。我認為當我們前進時,我們將不斷地看到這些原則在具體的技術實現中被採用。在Red Hat(我工作的地方),我們看到諸如3Scale⑮、Istio.io on Kubernetes⑯、Apache Camel⑰和諸如ActiveMQ Artemis⑱/Apache Qpid Dispatch Router⑲(包括非Red Hat技術,如Apache KafkaIMHO⑳)的訊息技術正被作為強大的構建塊來構建遵循以上原則的服務架構。