之前介紹了什么時候進行服務化,以及服務化拆分的兩種方式即橫向拆分和縱向拆分,還提到了引入微服務架構需要解決的問題,
這篇文章將進行介紹微服務架構的各個組成部分,
下圖是微服務架構的模塊圖,在具體介紹之前先來看下一次正常的服務呼叫的流程,

首先服務提供者(就是提供服務的一方)按照一定格式的服務描述,向注冊中心注冊服務,宣告自己能夠提供哪些服務以及服務的地址是什么,完成服務發布,
接下來服務消費者(就是呼叫服務的一方)請求注冊中心,查詢所需要呼叫服務的地址,然后以約定的通信協議向服務提供者發起請求,得到請求結果后再按照約定的協議決議結果,
而且在服務的呼叫程序中,服務的請求耗時、呼叫量以及成功率等指標都會被記錄下來用作監控,呼叫經過的鏈路資訊會被記錄下來,用于故障定位和問題追蹤,在這期間,如果呼叫失敗,可以通過重試等服務治理手段來保證成功率,
總結一下,微服務架構下,服務呼叫主要依賴下面幾個基本組件:
- 服務描述:RESTful API (HTTP)、XML 配置(RPC)、IDL 檔案(gRPC/Thrift)
- 注冊中心:注冊(服務提供者->注冊中心)、訂閱(服務消費者->注冊中心)、回傳(注冊中心->服務消費者)、通知(注冊中心->服務消費者)
- 服務框架:通信框架、通信協議、序列化和反序列化
- 服務監控(發現問題):指標收集、資料處理、資料展現
- 服務追蹤(定位問題):RequestId傳遞
- 服務治理(解決問題):單機故障-自動摘除、單IDC故障-自動切換、依賴服務不可用-熔斷
接下來進行介紹這些組件,
服務描述
服務呼叫首先解決的問題就是服務如何對外描述,服務描述主要解決對外服務的服務名是什么,呼叫需要提供哪些資訊,回傳格式是什么以及如何進行決議,
常用的服務描述方式包括 RESTful API、XML 配置以及 IDL 檔案三種,
RESTful API 方式通常用于 HTTP 協議的服務描述,RESTful API 方式的服務描述如下:
GET /sysDictoryDict/mapByUserId/{userId}
POST /enterprise/enterpriseDetail/top
PUT /enterprise/{enterpriseId}
DELETE /enterprise/{enterpriseId}
XML 配置方式多用作 RPC 協議的服務描述,通過 *.xml 組態檔來定義介面名、引數以及回傳值型別等,XML 配置方式的服務描述主要分三個步驟:
- 服務提供者定義介面,并實作介面
- 服務提供者行程啟動時,通過加載 server.xml 組態檔將介面暴露出去,
- 服務消費者行程啟動時,通過加載 client.xml 組態檔引入要呼叫的介面,
IDL 檔案方式通常用作 Thrift 和 gRPC 這類跨語言服務呼叫框架中,比如 gRPC 就是通過 Protobuf 檔案來定義服務的介面名、引數以及回傳值的資料結構,
服務描述方式比較
| 服務描述方式 | 使用場景 | 缺點 |
|---|---|---|
| RESTful API | 跨語言平臺,組織內外都適用 | 相比 TCP,HTTP 作為通信協議性能較差 |
| XML 配置 | Java 平臺,一般用于組織內部 | 不支持跨語言平臺 |
| IDL 檔案 | 跨語言平臺,組織內外都適用 | 修改/洗掉 PB 欄位不能向前兼容 |
注冊中心
接下來要解決的問題就是服務的發布和訂閱,也就是說你提供一個服務,如何讓外部想呼叫這個服務的人知道,就需要注冊中心出場了,服務提供者將自己提供的服務以及地址登記到注冊中心,服務消費者則從注冊中心查詢所需要呼叫的服務的地址,然后發起請求,
在整個微服務架構中,注冊中心是最基礎的核心服務之一,它記錄著服務和服務地址的映射關系,為服務提供方提供注冊、注銷功能,為服務消費方提供服務發現的功能,
注冊中心一般的作業流程是:
- 服務提供者在啟動時,根據服務發布檔案中配置的發布資訊向注冊中心注冊自己的服務,
- 服務消費者在啟動時,根據消費者組態檔中配置的服務資訊向注冊中心訂閱自己所需要的服務,
- 注冊中心回傳服務提供者地址串列給服務消費者,
- 當服務提供者發生變化,比如有節點新增或者銷毀,注冊中心將變更通知給服務消費者,
常見的注冊中心有 Netflix 的 Eureka、HashiCorp 的 Consul、雅虎的 Zookeeper、阿里的 Nacos 等,

服務框架
通過注冊中心,服務消費者就可以獲取到服務提供者的地址,有了地址后就可以發起呼叫,但在發起呼叫之前你還需要解決以下幾個問題,
- 服務通信采用什么協議?就是說服務提供者和服務消費者之間以什么樣的協議進行網路通信,是采用四層 TCP、UDP 協議,還是采用七層 HTTP 協議,還是采用其他協議?
- 資料傳輸采用什么方式?就是說服務提供者和服務消費者之間的資料傳輸采用哪種方式,是同步還是異步,是在單連接上傳輸,還是多路復用,
- 資料壓縮采用什么格式?通常資料傳輸都會對資料進行壓縮,來減少網路傳輸的資料量,從而減少帶寬消耗和網路傳輸時間,比如常見的 JSON 序列化、Java 物件序列化以及 Protobuf 序列化等,
這三部分就組成了一個完成的 RPC 呼叫框架,通信框架提供了基礎的通信能力,通信協議描述了通信契約,而序列化和反序列化則用于資料的編/解碼,一個通信框架可以適配多種通信協議,也可以采用多種序列化和反序列化的格式,
- 通信框架:解決客戶端和服務端如何建立連接、管理連接以及服務端如何處理請求的問題,
- 通信協議:解決客戶端和服務端采用哪些資料傳輸協議的問題,
- 序列化和反序列化:解決客戶端和服務端采用哪種資料編碼的問題,
服務監控
可以正常發起服務呼叫后,就需要對呼叫情況進行監控,以了解服務是否正常,通常來講,服務監控主要包括三個流程,
- 指標收集:把每一次服務呼叫的請求耗時以及成功與否收集起來,并上傳到集中的資料處理中心,
- 資料處理:根據每次呼叫的請求耗時以及成功與否等資訊,就可以計算每秒服務請求量、平均耗時以及成功率等指標,
- 資料展示:通常都是將資料展示在 Dashboard 面板上,并且每隔 10s 等間隔自動重繪,用作業務監控和報警等,
服務追蹤
記錄服務呼叫經過的每一層鏈路,以便進行問題追蹤和故障定位,
服務追蹤的作業原理大致如下:
- 服務消費者發起呼叫前,會在本地按照一定的規則生成一個 requestid,發起呼叫時,將 requestid 當作請求引數的一部分,傳遞給服務提供者,
- 服務提供者接收到請求后,記錄下這次請求的 requestid,然后處理請求,如果服務提供者繼續請求其他服務,會在本地再生成一個自己的 requestid,然后把這兩個 requestid 都當作請求引數繼續往下傳遞,
以此類推,通過這種層層往下傳遞的方式,一次請求,無論最后依賴多少次服務呼叫、經過多少服務節點,都可以通過最開始生成的 requestid 串聯所有節點,從而達到服務追蹤的目的,

常用的服務追蹤有 Twitter 的 Zipkin、華為的 skywalking、Uber 的 jaeger、大眾點評的 CAT等,
服務治理
服務治理就是保證在各種意外情況下,服務呼叫仍然能夠正常進行,
在生產環境中,經常會遇到下面幾種情況:
- 單機故障:服務治理可以通過一定的策略,自動摘除故障節點,就能保證單機故障不會影響業務,
- 單 IDC 故障:服務治理可以通過自動切換故障 IDC 的流量到其他正常 IDC,可以避免因為單 IDC 故障引起的大批量業務受影響,
- 依賴服務不可用:服務治理可以通過熔斷,在依賴服務例外的情況下,一段時期內停止發起呼叫而直接回傳,既保證了服務消費者能夠不被拖垮,也給服務提供者減少壓力,使其能夠盡快恢復,
還有其他服務治理的手段比如自動擴縮容、負載均衡、服務路由以及服務容錯等,
總結
主要對微服務架構中的組件進行了介紹,微服務架構主要由服務描述、注冊中心、服務框架、服務監控、服務追蹤以及服務治理等組成,

參考
https://dwz.cn/FscvpObJ
https://dwz.cn/3PTGdySt
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/46437.html
標籤:架構設計
上一篇:從單體應用走向服務化
下一篇:一個極簡的分布式檔案系統
