天天看點

.net中調用esb_微服務架構的應用內建:服務網格并不是 ESB

本文要點

  • 在企業級軟體開發中,API、服務、資料和系統內建是最具挑戰性,同時也是最重要的需求;
  • 過去,我們曾經将這些獨立的應用以點對點的風格內建在一起,随後這種方式被 ESB(企業服務總線,Enterprise Service Bus)風格所代替,與之同時出現的還有面向服務架構(Service Oriented Architecture,SOA);
  • 随着微服務和“雲原生”架構的普及,出現了“服務網格”的概念。服務網格的核心思想是将所有業務邏輯的代碼作為服務的一部分,同時将網絡通信相關的邏輯放到到服務間通信基礎設施之中。
  • 因為服務網格提供了一些 ESB 的功能,是以有人将其誤解為分布式 ESB,讓它也負責應用內建。這是不正确的。
  • 服務網格隻是用來在服務間進行通信的基礎設施,開發人員不應該在服務網格中建構任何業務邏輯。有一些其他的架構和庫可以用來實作雲原生企業應用的內建模式。

在企業級軟體應用開發中,長期以來,API、服務、資料以及系統的內建都是最具挑戰性同時也是最基本的需求。

.net中調用esb_微服務架構的應用內建:服務網格并不是 ESB

在過去,我們會将這些獨立的應用以點對點的方式進行內建,這種方式随後被企業服務總線(enterprise service bus,ESB)和面向服務架構(service-oriented architecture,SOA)所替代。

但是,在現代微服務和雲原生架構中,我們很少再去讨論應用內建了。但這并不意味着這種現代架構已經解決了企業應用內建的所有挑戰。

應用內建的挑戰幾乎沒有什麼變化,但是我們解決它們的方式卻發生了變化。

從 ESB 到智能端點和啞管道

大多數采用 SOA 的企業都會使用 ESB 作為中心總線,以連接配接和內建所有獨立的 API、服務、資料和系統。

如果給定的業務場景需要與組織中不同的實體進行通信的話,ESB 的職責就是探測所有的實體并建立組合功能。

是以,通常來講,ESB 解決方案是所有内置內建功能的動力源,例如到不同系統和 API 的連接配接器、消息路由、轉換、彈性通信、持久性和事務。

.net中調用esb_微服務架構的應用內建:服務網格并不是 ESB

圖 1:使用 USB 進行內建

但是, 微服務架構 傾向于通過構造智能端點和啞管道來 替代 ESB ,這意味着我們的微服務必須要負責所有的應用程式內建。

.net中調用esb_微服務架構的應用內建:服務網格并不是 ESB

智能 ESB 去中心化的一個代價就是微服務代碼的複雜性會明顯增加,因為除了服務的業務邏輯之外,它們必須還要處理這些應用內建的功能。例如,圖 2 展現了多個作為智能端點的微服務(B、F 和 G),它們同時包含了與多個其他服務通信的結構和業務本身的邏輯。

.net中調用esb_微服務架構的應用內建:服務網格并不是 ESB

圖 2:微服務的服務間通信群組合

微服務架構的另一項挑戰是如何建構不屬于服務業務邏輯的特性,如彈性通信、傳輸級别的安全性、釋出統計資料、将跟蹤資料釋出到可觀察性工具等。服務本身必須将這些特性作為服務邏輯的一部分來進行實作。在每個微服務中實作所有的這些特性是非常複雜的,如果我們的服務是使用多語言(polyglot)實作的話,這會極大地增加相關的工作量,而服務網格可以解決這個問題。

.net中調用esb_微服務架構的應用內建:服務網格并不是 ESB

圖 3:實際的服務網格

服務網格的核心思想是将所有業務邏輯的代碼作為服務的一部分,同時将網絡通信相關的邏輯放到到服務間通信基礎設施之中。在使用服務網格的時候,給定的微服務不會直接與其他的微服務進行通信。服務和服務之間的通信會通過一個額外的軟體元件來進行,這個元件運作在服務的程序之外,叫做服務網格代理或 sidecar 代理。sidecar 程序和服務位于同一個虛拟機(VM)或 Pod(Kubernetes)中。sidecar 代理層也被成為資料平面(data plane)。所有的 sidecar 代理都會由控制平面(control plane)來進行控制,服務間通信相關的配置都會用到這裡。

服務網格并不是用來進行應用內建的

因為服務網格提供了一些 ESB 的功能,是以有人将其誤解為分布式 ESB,讓它也負責應用內建。這是不正确的。服務網格隻是用來在服務間進行通信的基礎設施,我們不應該在服務網格中建構任何業務邏輯。假設我們有三個微服務,名為 X、Y 和 Z,它們以請求 / 響應的方式進行通信,為了實作業務功能,X 需要與 Y 和 Z 進行通信(參加圖 4)。業務邏輯的組合應該是微服務 A 的代碼,服務網格的 sidecar 不應該包含任何與組合邏輯相關的内容。

.net中調用esb_微服務架構的應用內建:服務網格并不是 ESB

圖 4:服務組合邏輯與服務網格

類似的,對于使用事件驅動通信的服務來講,服務的代碼應該處理所有的業務邏輯細節(值得一提的是,服務網格還沒有完全支援事件驅動架構)。是以,即便我們基于服務網格運作微服務或雲原生應用,這些服務和應用的內建依然是必要的。在現代微服務和雲原生架構時代,應用內建是最關鍵的需求之一,但在很大程度上它依然是隐形的需求。

.net中調用esb_微服務架構的應用內建:服務網格并不是 ESB

微服務和雲原生應用的內建

在微服務和雲原生應用中,應用內建或建構智能終端都涉及到內建微服務、API、資料和系統。這些內建需求涉及的範圍從幾個微服務之間的內建到與單體子系統的內建,再到建立反腐敗層(anti-corruption layer)。深入研究微服務和雲原生應用程式中的應用程式內建需求,我們會發現在應用程式內建架構中需要具備以下關鍵功能:

  • 內建運作時必須是雲原生的,能夠平穩運作在 Docker/Kubernetes 中,并且提供與雲原生生态系統的無縫內建。
  • 它需要支援服務編排(orchestrations)/ 活動組合,這樣給定的服務要包含調用多個其他服務的邏輯,進而能夠組合業務功能。
  • 它需要支援服務協同(choreography)/ 反應式組合,這樣服務間通信可以通過同步的事件驅動通信來實作,避免出現包含服務互動邏輯的中心化服務。
  • 它必須具有對各種消息協定(HTTP、gRPC、GraphQL、Kafka、NATS、AMQP、FTP、SFTP、WebSockets、TCP)的内置抽象。
  • 它必須要支援消息和服務調用的分叉(forking)、連接配接(joining)、分割(splitting)、循環(looping)和聚合(aggregation)。
  • 它需要支援存儲和轉發、持久化投遞和幂等消息等技術。
  • 它必須具有消息類型映射和轉換的功能。
  • 它必須能夠與 SaaS(如 Salesforce)、專有方案(如 SAP)和遺留系統進行內建。
  • 應該具有面向業務邏輯的消息路由。
  • 它必須支援以補償的方式實作分布式事務。
  • 它必須具備長時間運作的工作流。
  • 反腐敗層必須能夠連接配接微服務和單體子系統。

在任何微服務和雲原生應用中,這些功能都是很常見的,但是從頭進行建構可能是一項艱巨的任務。這也是為什麼在建構微服務和雲原生應用時,仔細分析這些功能并基于內建需求選擇合适的技術和架構為何如此重要。例如,如果我們要建構的服務需要複雜的編排邏輯,那麼我們選擇的架構或技術應該能讓這種類型的組合更易于編寫。如果我們想要建構的服務要長期運作并且具備補償功能,那麼就要選擇一個内置工作流和補償功能的架構(參見 InfoQ 的文章“ 事件、流程和長期運作的服務:工作流自動化的現代解決方案 ”,Martin Schimak 和 Bernd Rücker 深入分析了目前面向雲原生架構的工作流技術)。

盡管應用內建被大多數的微服務專家所忽視,但是像 Christian Posta(Red Hat 前首席架構師,Solo.io 的 Field CTO)這樣的文章作者已經強調了應用內建的重要性,比如 Posta 的部落格文章 不能将應用程式的安全性和正确性放到 Istio 或其他服務網格上 。Bilgin Ibryam 在 InfoQ 文章 後 Kubernetes 時代的微服務 一文中,強調了雲原生架構中應用內建的去中心化,以及如何基于服務網格建構應用內建。

CNCF 視野下的開發和內建

雲原生計算基金會(Cloud Native Computing Foundation,CNCF)處在建構微服務和雲原生應用程式的最前沿,它的目标是建構可持續的生态系統,并圍繞一組高品質的項目打造一個社群,将容器編排作為微服務架構的一部分。CNCF 托管由開源技術和架構組成的項目,這些項目可以實作微服務或雲原生架構的不同方面。我們可以看一下這些應用內建技術位于技術棧的什麼位置。

CNCF 推薦的 雲原生路徑 有一個應用定義和開發(App Definition and Development)部分,但是沒有專門的應用開發或內建的分類。考慮到應用程式內建的重要性,我們可以看到它将來會納入 CNCF 之中。圖 5 展示了應用定義和開發下的應用內建技術。

.net中調用esb_微服務架構的應用內建:服務網格并不是 ESB

圖 5:未來 CNCF 中的應用內建

應用內建相關的技術

盡管有很多單體的應用內建技術可供使用,但是,它們中的大多數并不适合雲原生或微服務架構。在已有的內建提供商中,隻有很少一部分為它們的産品和工具實作了針對雲原生的變種。

有一些專門的內建架構,可以在應用內建領域實作通用的內建模式。通常,大多數這樣的技術都是從傳統的基于 ESB 的內建方式中繼承而來的,但是它們都經過了修改,并且可以直接內建到雲原生架構中:

  • Apache Camel/Camel-K 是最流行的開源內建架構之一,Camel-K 項目基于 Camel 運作時為 Kubernetes 生态系統提供了無縫支援。
  • WSO2 Micro Integrator 是開源 WSO2 企業級內建平台的雲原生變種形式。Micro Integrator 提供了輕量級的內建運作時,它能在 Kubernetes 生态系統中直接運作。
  • 盡管 Spring Integration 沒有專門在 Kubernetes 上的運作時版本,但是它能夠很好地用到雲原生架構中的應用內建功能中。

一些應用開發架構也能滿足應用內建的需求:

  • Spring Boot 本身并不是一個內建架構,但是它具備應用內建所需的很多重要功能。
  • Vert.x 是一個用于建構反應式雲原生應用的工具包,它也能用來進行應用內建。
  • Micronaut 是一個現代的、基于 JVM 的全棧架構,能夠用來構模組化塊化和易于測試的微服務以及 serverless 應用。該架構内置了很多內建抽象,并且避免了傳統架構(如 Spring)的複雜性。
  • Go 、 JavaScript/Node.js 等程式設計語言有一些内置的或者可以以庫的形式使用的應用內建特性。一些新興的語言,比如 Ballerina ,語言本身就提供了對內建的抽象。
  • Quarkus 是一個新的 Kubernetes 原生 Java 棧,它針對 GraalVM 和 OpenJDK 進行了定制,由最好的 Java 庫和标準組裝而成。它組合了多個應用開發庫,比如 RESTeasy、Camel、Netty 等。

結論

在将單體應用拆分為微服務和雲原生應用的過程中,如何連接配接這些應用的需求變得越來越具有挑戰性。服務和應用程式分散在網絡中,并通過不同的通信結構連接配接。實作任何的業務場景都需要微服務內建,這需要作為服務實作邏輯的一部分來完成。是以,在微服務和雲原生架構時代,雲原生應用內建是最關鍵的需求之一,但它在很大程度上是隐形的需求。

服務網格模式克服了微服務內建方面的一些挑戰,但是它隻提供了服務間通信的通用特性,這是獨立于服務的業務邏輯的,是以業務場景相關的應用內建邏輯還是要在服務級别來實作。是以,最重要的是選擇合适的開發技術來建構內建服務,并将服務組合在一起所需的開發時間最小化。有一些架構和技術正在出現,以滿足雲原生環境中應用內建相關的需求,我們需要根據每個特定的用例來評估這些技術。