天天看點

Java微服務架構的核心要點和實作原理(基于最新的架構)

作者:架構淺水灣

Java微服務架構的核心要點和實作原理(基于最新的架構)

微服務去中心化治理

Java微服務架構的核心要點和實作原理(基于最新的架構)

上圖中, 外部服務和内部服務屬于 API 網關, 所有的服務由統一的 API 網關進行管理.

比如外部應用要調用服務1, 就會經過 API 網關(外部服務), 内部應用也是一樣的. 如果服務N要調用服務2, 則也需要通過 API 網關進行調用.

這樣看起來很規範, 但是每個使用者請求時隻要有服務之間的互動, 則都會從 API 網關進行路由, 業務量增大後, 在很大程度上增加了 API 網關的調用 TPS, API 網關很快就遇到了性能瓶頸.

微服務倡導去中心化的治理, 不推薦每個服務都使用相同的标準和技術來開發和使用服務. 也就是說你可以使用 C++ 開發一個服務, 來對接 Java 開發的另一個服務.

對于異構系統之間的互動标準, 可以使用 Thrift 遠端調用架構使用中間語言 (IDL) 來定義接口, 中間語言是獨立于任何語言的, 并提供了工具來生成中間語言, 以及在中間語言與具體語言之間的代碼轉換.

最後談下微服務架構是否就一定是去中心化的, 如果一個微服務架構沒有使用微服務網關那它一定是去中心化的, 如果使用了微服務網關就需要進行判斷.

微服務網關是否隻提供了類似Dubbo服務注冊和發現能力, 實際通路仍然是點對點的服務調用, 如果是這種模式也可以了解為整個微服務架構是去中心化的. 如果一個微服務網關提供了完全的對被調用系統的安全隔離, 包括提供了對每次消息調用的日志追溯能力, 那麼微服務網關就是一個不可繞過的中心節點, 整個微服務架構也不再是去中心化的架構.

微服務的互動模式

讀者容錯模式

讀者容錯模式指微服務化中服務提供者和消費者之間如何對接口的改變進行容錯. 也就是說, 消費者擷取到提供者傳回的資料時, 無論這個資料如何變化, 我們隻需要從中擷取到我們想要的資料, 可以忽略新的消息項、可選的消息項等不需要的資料.

隻有當消費者不能完全識别接收到的消息, 或者無法通過識别的資訊繼續處理流程時, 才抛出異常.

去資料共享模式

在微服務領域, 微服務之間的互動通過定義良好的接口來實作, 不允許使用共享資料來實作.

在實踐的過程中, 有些方案的設計使用緩存或者資料庫作為兩個服務之間的紐帶, 在業務流程的處理過程中, 為了處理簡單, 前一個服務将中間結果存入資料庫或緩存, 下一個服務從緩存或資料庫中拿到資料繼續處理. 如下圖:

Java微服務架構的核心要點和實作原理(基于最新的架構)

這種互動流程的缺點如下:

  • 使得微服務之間的互動除了接口契約, 還存在資料庫存儲契約.
  • 上遊的資料庫格式發生變化時, 可能導緻下遊的處理邏輯出現問題.
  • 多個服務共享一個資源服務, 對資源服務的運維難以劃清職責和界限.
  • 在做雙機獨立部署時, 需要考慮服務和資源的路由情況, 跨機房的服務調用不能使用獨立的資源部署模式, 是以難以實作服務自治.

是以, 在設計微服務架構時, 一定不要共享緩存和資料庫等資源, 也不要使用總線模式, 服務之間的通信和互動隻能依賴定義良好的接口, 通過使用 RESTful 樣式的 API 或透明的 RPC 調用架構.

消費者驅動契約模式

消費者驅動契約模式用來定義服務之間互動接口改變的規則. 分為: 提供者契約、消費者契約、消費者驅動的契約.

  1. 提供者契約: 提供者提供了什麼功能和消息格式, 各消費者不論實際需要多少功能都要無條件地遵守這些約定.
  2. 消費者契約: 是對某個消費者的需求進行更為精确的描述, 在一次具體的服務業互動場景下, 代表消費者需要提供者提供功能中的哪些部分資料. 消費者契約可以被用來辨別現有的提供者契約, 也可以用來發現一個尚未明确的提供者契約.
  3. 消費者驅動的契約: 代表服務提供者向其所有目前消費者承諾遵守的限制. 一旦各消費者把自己的具體期望告訴提供者, 則提供者無論在什麼時間和場景下, 都不能打破契約.

在實作的服務互動設計中, 上面這三種契約是同時存在的, 筆者(這本書的作者)所在的支付平台裡, 交易系統在完成一筆支付後, 需要到賬務系統為商戶入賬, 這個過程中, 服務契約表現如下.

  • 生産者契約: 賬務系統提供 Dubbo 服務化接口, 參數為商戶賬号ID、入賬訂單号和入賬金額.
  • 消費者契約: 賬務系統傳回 DTO, 包含賬戶賬戶ID、入賬訂單号、入賬金額、入賬時間、賬務流水号、入賬狀态等, 而交易系統隻需要使用其中的入賬訂單号和入賬狀态.
  • 消費者驅動的契約: 為了保證資金安全, 交易系統作為入賬的發起者向賬務提出要求, 需要賬務做幂等和濾重處理, 對重複的入賬請求進行攔截; 賬務系統在接受這個契約後, 即将來有任何改變, 也不能打破這個限制, 否則就造成資金流失, 這在金融系統中是最嚴重的問題.
Java微服務架構的核心要點和實作原理(基于最新的架構)

服務提供者契約是服務提供者單方面定下的規則, 而一個消費者契約會成為提供者契約的一部分, 多個服務消費者可以對服務提供者提出限制, 服務提供者需要在将來遵守服務消費者提出的契約, 這就是消費者驅動的契約.

總結

  1. 當調用任意一個服務時, 都需要經過同一個服務(API 網關, 也就是說每個服務都不能繞過這個節點), 這就是中心化; 微服務提倡去中心化治理, 因為當業務量增加後可能會導緻 API 網關出現性能瓶頸.
  2. 不推薦每個服務都使用相同的标準和技術來開發和使用服務. 可以使用 C++ 開發一個服務來調用 Java 服務.
  3. 微服務推薦使用 RESTful 樣式的 API 或透明的 RPC 調用架構, 進行互動, 不推薦使用資料共享模式.
  4. 讀者容錯模式就是在消費者或提供者接口改變時進行容錯, 比如提供者傳回資料中新增項後, 消費者指擷取需要的資料.
  5. 提供者契約: 服務提供者提供了哪些約定, 比如提供了什麼功能和消息格式.
  6. 消費者契約: 是對某個消費者的需求進行更為精确的描述, 在一次具體的服務業互動場景下, 代表消費者需要提供者提供功能中的哪些部分資料.
  7. 消費者驅動契約: 例如服務端調整架構或接口調整而對消費者不透明, 導緻接口調用失敗, 而CDC則是以消費者提出接口契約, 交由服務提供方實作, 并以測試用例對契約進行産生限制, 是以服務提供方在滿足測試用例的情況下可以自行更改接口或架構實作而不影響消費者.

繼續閱讀