天天看點

微服務架構學習(三):微服務架構選型

前言

前面主要了解什麼是微服務,它與傳統的單體服務有什麼差別,他們各自的優缺點以及為什麼我要考慮微服務改造。從現在開始,我們深入的研究一下,微服務架構它有哪些比較常見的選型,并且了解一下一些常見的專業名稱含義。

服務架構選型

目前從我在網上看了那麼多的資料來說,服務架構是一個比較成熟的領域,有太多可選項。本次我們主要了解幾個最為突出的兩個服務架構,Spring Cloud 、 Dubbo 、gRPC。

Spring Cloud

Spring Cloud基于 Spring Boot,為微服務體系開發中的架構問題,提供了一整套的解決方案——服務注冊與發現,服務消費,服務保護與熔斷,網關,分布式調用追蹤,分布式配置管理等。由于 Spring 社群的影響力和 Netflix 的背書,目前可以認為是建構 Java 微服務的一個社群标準。

基于 Spring 的架構本質上可以認為是一種 RESTful 架構(不是 RPC 架構),序列化協定主要采用基于文本的 JSON,通訊協定一般基于 HTTP。RESTful 架構天然支援跨語言,任何語言隻要有 HTTP 用戶端都可以接入調用,但是用戶端一般需要自己解析 payload。目前 Spring 架構也支援 Swagger 契約程式設計模型,能夠基于契約生成各種語言的強類型用戶端,極大友善不同語言棧的應用接入,但是因為 RESTful 架構和 Swagger 規範的弱契約特性,生成的各種語言用戶端的互操作性還是有不少坑的。

Dubbo

Dubbo是阿裡多年建構生産級分布式微服務的技術結晶,服務治理能力非常豐富,在國内技術社群具有很大影響力。Dubbo 本質上是一套基于 Java 的 RPC 架構,當當 Dubbox 擴充了 Dubbo 支援 RESTful 接口暴露能力。

Dubbo 主要面向 Java 技術棧,跨語言支援不足是它的一個弱項,另外因為治理能力太豐富,以至于這個架構比較重,完全用好這個架構的門檻比較高,但是如果你的企業基本上投資在 Java 技術棧上,選 Dubbo 可以讓你在服務架構一塊站在較高的起點上,不管是性能還是企業級的服務治理能力,Dubbo 都做的很出色。新浪微網誌開源的 Motan也不錯,功能和 Dubbo 類似,可以認為是一個輕量裁剪版的 Dubbo。

gRPC

gRPC是谷歌近年新推的一套 RPC 架構,基于 protobuf 的強契約程式設計模型,能自動生成各種語言用戶端,且保證互操作。支援 HTTP2 是 gRPC 的一大亮點,通訊層性能比 HTTP 有很大改進。Protobuf 是在社群具有悠久曆史和良好口碑的高性能序列化協定,加上 Google 公司的背書和社群影響力,目前 gRPC 也比較火。

目前看 gRPC 更适合内部服務互相調用場景,對外暴露 RESTful 接口可以實作,但是比較麻煩(需要 gRPC Gateway 配合),是以對于對外暴露 API 場景可能還需要引入第二套 RESTful 架構作為補充。總體上 gRPC 這個東西還比較新,社群對于 HTTP2 帶來的好處還未形成一緻認同,建議謹慎投入,可以做一些試點。

概念了解

通讀上面的介紹,發現有很多名詞,其實讀下來并不是很了解,具體是什麼含義,是以我要對一些不了解的概念,挑出來進行了解和加深印象。

熔斷

一般在微服架構中,有一個元件角色叫熔斷器。顧名思義,熔斷器起的作用就是在特定的場景下關掉目前的通路,進而起到保護整個系統的效果

服務熔斷:當下遊的服務因為某種原因突然變得不可用或響應過慢,上遊服務為了保證自己整體服務的可用性,不再繼續調用目标服務,直接傳回,快速釋放資源。如果目标服務情況好轉則恢複調用。

假設有這麼一個場景,有A, B, C, D四個獨立服務,A會依賴B,C,D;當D發生負載過高或網絡異常等導緻響應過慢或逾時時,很可能A會是以堆積過多的等待連結,進而導緻A的狀态也轉為異常,後面依賴到A的其他服務跟着發生鍊式反應,這将會導緻大面積的服務不可用,即使本來是一些沒有依賴到B,C,D的服務。如下圖所示:

微服務架構學習(三):微服務架構選型

這不是我們希望看到的結果,是以這個時候熔斷器可以派上用場。最簡單的做法,我們為每個依賴服務配置一個熔斷器開關,正常情況下是關閉的,也就是可以正常發起請求;當請求失敗(逾時或者其他異常)次數超過預設值時,熔斷器自動打開,這時所有經過這個熔斷器的請求都會直接傳回失敗,并沒有真正到達所依賴的服務上。這時服務A本身仍然是能正常服務的。

業内目前流行的熔斷器很多,例如阿裡出的Sentinel,以及最多人使用的Hystrix。

RPC

說到RPC,就要簡單聊聊REST。什麼是REST?REST是一種架構風格,指的是一組架構限制條件和原則。滿足這些限制條件和原則的應用程式或設計就是 RESTful。REST規範把所有内容都視為資源,網絡上一切皆資源。

REST并沒有創造新的技術,元件或服務,隻是使用Web的現有特征和能力。 可以完全通過HTTP協定實作,使用 HTTP 協定處理資料通信。REST架構對資源的操作包括擷取、建立、修改和删除資源的操作正好對應HTTP協定提供的GET、POST、PUT和DELETE方法。

什麼是RPC? RPC是遠端過程調用(Remote Procedure Call)的縮寫形式。SAP系統RPC調用的原理其實很簡單,有一些類似于三層構架的C/S系統,第三方的客戶程式通過接口調用SAP内部的标準或自定義函數,獲得函數傳回的資料進行處理後顯示或列印。

簡單的了解是一個節點請求另一個節點提供的服務

那麼RPC架構要做到的最基本的三件事:

1、服務端如何确定用戶端要調用的函數;

在遠端調用中,用戶端和服務端分别維護一個【ID->函數】的對應表, ID在所有程序中都是唯一确定的。用戶端在做遠端過程調用時,附上這個ID,服務端通過查表,來确定用戶端需要調用的函數,然後執行相應函數的代碼。

2、如何進行序列化和反序列化;

用戶端和服務端互動時将參數或結果轉化為位元組流在網絡中傳輸,那麼資料轉化為位元組流的或者将位元組流轉換成能讀取的固定格式時就需要進行序列化和反序列化,序列化和反序列化的速度也會影響遠端調用的效率。

3、如何進行網絡傳輸(選擇何種網絡協定);

多數RPC架構選擇TCP作為傳輸協定,也有部分選擇HTTP。如gRPC使用HTTP2。不同的協定各有利弊。TCP更加高效,而HTTP在實際應用中更加的靈活。

契約程式設計模型

資料類型的設計者需要說明前提條件(用例在調用某個方法前必須滿足的條件)、後置條件(實作在方法傳回時必須達到的要求)和副作用(方法可能對對象狀态産生的任何其他變更)。

這是Bertrand Meyer在EL語言中提出的一個設計風格,流行了近20年。不過現在比較少用,不是很流行了。

目前在Test-Driven Development (TDD)用得比較多,很少帶進主code中。

缺點就是A drawback of using these methods and Ensuring is that you can’t disable these checks

in production也就是在生産中無法自由地把這些契約disable。

真要引入這種風格到你的code時,得編寫一個子產品來随時關閉這種功能。

HTTP2

HTTP/2是現行HTTP協定(HTTP/1.x)的替代,但它不是重寫,HTTP方法/狀态碼/語義都與HTTP/1.x一樣。HTTP/2基于SPDY3,專注于性能,最大的一個目标是在使用者和網站間隻用一個連接配接(connection)。

為什麼需要HTTP/2 ?因為影響一個HTTP網絡請求的因素主要有兩個:帶寬和延遲。在今天的網絡情況下,帶寬一般不再是瓶頸,是以我們主要讨論下延遲。延遲一般有下面幾個因素:

  1. 浏覽器阻塞(Head-Of-Line Blocking):浏覽器會因為一些原因阻塞請求。
  2. DNS查詢。
  3. 建立連接配接(Initial connection):HTTP基于 TCP 協定,TCP的3次握手和慢啟動極大增加延遲。

HTTP/1.x的缺陷:

連接配接無法複用:連接配接無法複用會導緻每次請求都經曆三次握手和慢啟動。三次握手在高延遲的場景下影響較明顯,慢啟動則對檔案類大請求影響較大。

HTTP/1.0傳輸資料時,每次都需要重建立立連接配接,增加延遲。

1.1雖然加入keep-alive可以複用一部分連接配接,但域名分片等情況下仍然需要建立多個connection,耗費資源,給伺服器帶來性能壓力。

Head-Of-Line Blocking:導緻帶寬無法被充分利用,以及後續健康請求被阻塞。HOLB是指一系列包(package)因為第一個包被阻塞;HTTP/1.x中,由于伺服器必須按接受請求的順序發送響應的規則限制,那麼假設浏覽器在一個(tcp)連接配接上發送了兩個請求,那麼伺服器必須等第一個請求響應完畢才能發送第二個響應——HOLB。

協定開銷大:HTTP/1.x中header内容過大(每次請求header基本不怎麼變化),增加了傳輸的成本。

安全因素:HTTP/1.x中傳輸的内容都是明文,用戶端和服務端雙方無法驗證身份。

HTTP/2的新特性

因為HTTP/1.x的問題,人們提出了各種解決方案。比如希望複用連接配接的長連結/http long-polling/websocket等等,解決HOLB的Domain Sharding(域名分片)/inline資源/css sprite等等。

不過以上優化都繞開了協定,直到谷歌推出SPDY,才算是正式改造HTTP協定本身。降低延遲,壓縮header等等,SPDY的實踐證明了這些優化的效果,也最終帶來HTTP/2的誕生。

  1. 新的二進制格式(Binary Format)
  2. Header壓縮
  3. 流(stream)和多路複用(MultiPlexing)

    3.1 流量控制(Flow Control)

    3.2 流優先級(Stream Priority)

  4. Server Push
Protobuf

protocol buffers 是一種語言無關、平台無關、可擴充的序列化結構資料的方法,它可用于(資料)通信協定、資料存儲等。

Protocol Buffers 是一種靈活,高效,自動化機制的結構資料序列化方法-可類比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更為簡單。

你可以定義資料的結構,然後使用特殊生成的源代碼輕松的在各種資料流中使用各種語言進行編寫和讀取結構資料。你甚至可以更新資料結構,而不破壞由舊資料結構編譯的已部署程式。

簡單來講, ProtoBuf 是結構資料序列化[1] 方法,可簡單類比于 XML[2],其具有以下特點:

  • 語言無關、平台無關。即 ProtoBuf 支援 Java、C++、Python 等多種語言,支援多個平台
  • 高效。即比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更為簡單
  • 擴充性、相容性好。你可以更新資料結構,而不影響和破壞原有的舊程式

總結

總的來說,本次的内容概念性的東西太多了,需要了解和消化,但是其中微服務的大體選型方向已經明了,接下來我準備繼續深入的研究一下Spring Cloud 和 Dubbo ,順帶看看gRPC

繼續閱讀