聊聊分散式架構的服務治理


大部分開發者聊到 微服務架構分散式系統,都會談到 服務發現 (Service Discovery) 這個東西,讓開發者的應用程式可以透過他知道別的服務的位置。

這是視角的問題,開發者習慣從 App 內部往外 看 (白箱),由內而外通訊需要知道的就是一個服務清單,然後對照相關的資訊。服務發現 (Service Discovery) 就是這樣的東西,大部分也會順便負責一些 Health Check、Service Status 的提供,但是有個很關鍵的問題是大部分服務發現沒有的,就是服務的 生命週期管理服務實例 (Service Instance) 管理 。

而實際上,系統是要給人用的,系統需要被治理、管理,這個角度則是 由外往裡 看的,也就是 黑箱 的概念。

特別整理一段跟朋友的對話,聊聊這幾年我對於服務治理的看法。


從對談中疏理的想法

這段是與 AWS SA Kim 的對話,徵得他的同意,我把內容做適度篩選後,整理在這裡。

Kim:

Hello Rick

問個問題一下,你們在玩 k8s 的過程中,有沒有發現從軟體功能角度看服務治理這件事情有缺一塊?就我的感受上來說,k8s 雖然提供了基於 DNS 的服務註冊與查找的機制,但是從軟體端的服務之間的相互呼叫,應該是以 SDK or API 層次來作動。意味著,我們不太會想要自己去乖乖 query DNS,或者手動再去配置 xxservice.cluster.local 這些對應。我一直覺得缺一個類似 JNDI 的列表清單,或者是得自己手動寫一些 service list / enumeration 來動態完成自動對應 註冊在 kube-dns / coreDNS 上的那些 services。

有一個最後一哩路需要所有團隊都搭配要做。就是每一次的版本發布時都要能很好標明版號,已經可以做出支援不同版本的 Service API Call,這部分必須決定是從不同的 runtime 來支持,還是要從程式碼實際的 feature 上支持(在同一個版本發佈裡)。

Rick:

我現在的做法是 Service Catalog (清單生命週期管理) + Service Discovery (Consul, 線上狀態管理),搭配 開發給服務 使用的 SDK,把這些接起來。

特別是有一些定義的問題:

  1. 大家對於 “Service” 的定義落差很大
  2. 大部分的 APP Team 對你說的 Service List 無感, 除非炸鍋. 最近半年內,有人跟我反應這問題幾次。
  3. Service Definition 的規範: Service list 還是要被管理,最後還是回到類似 DNS 的管理概念,需要有 FQDN 做全公司範圍的 Namespace 管理. 管理的前提要有清楚的定義,包含生命週期、資料結構、權責 … 等。
  4. 你說的版本管理 semver, 我們內部很多團隊其實是沒有版本的觀念. 所以 App 主動上報 Service Discovery 除了名字,還要有 版本 以及 部署資訊,這兩者是一對多,像是 ServiceId=gtcafe.ooxx, Version=v1.0.0, 而每個版本,則會有多個部署,像是 InstanceId=deploy1, InstanceId=deploy2。對應到容器概念,就是 docker image vs container (runtime) 的概念。

基於這個基礎建設,才會有一個全公司範圍的 Service Status Board,做 Distributed Tracing 才有意義。系統有異常的時候,就可以知道這條 請求路徑 經過哪一些服務,進而探索哪一個點 (服務) 有問題,請那個團隊處理。

補充:不管是新增專案需求,要做 Feature / Function,還是線上系統炸鍋找問題,都要面對我說的 請求路徑 梳理的問題,這點也是我在文章:系統發生異常時,第一時間如何快速止血? 提到的第一點,這都是要梳理的,套句我在 災難演練 引用的話:你選擇面對他,還是讓他來找到你?

Kim:

這大工程,還蠻需要大家支持的。

Rick:

公司還是業務優先,這種基礎架構的工作要花很多時間向上溝通,取得高層的支持很重要,然後才是落地的工作。

Kim:

因為我以前的經驗是,當我有 8 個團隊要協作時,沒有人想要離開 IDE 與 SDK 的程式碼呼叫調用,叫他們要去 hard code 會被嗆爆。最理想的狀況是當接到一個新 feature 時,知道有某些功能會跨服務呼叫,第一時間就是先吧 Service List 的 Interface ENUM 都搞定,然後才開始提供協作的 Contract Interface API

Rick:

我的經驗,知道有某些功能會跨服務呼叫 這點就不太能搞定了,實際經驗是,很多團隊根本搞不清楚 feature 與其他服務之間的關係。很多時候都在上線前 Infra Review 時提醒相關的服務依賴,發現問題不少。2019 年我就在用 Service Catalog 的概念,當時沒有什麼系統化,單純是列管,現在我已經有相對完整的想法、做法、落地的配套、實際的成效評估。剩下就是 溝通 溝通 溝通

每年雙十一,都希望能有一個全公司範圍的 Services Dashboard,能夠快速掌握整個產品系統的狀況。不過說歸說,我上面提到的東西沒規範好,要系統化的難度很高。

註記:所以我才會寫下這篇 系統發生異常時,第一時間如何快速止血?

Rick:

其實聊到現在,我的想法跟 K8s 完全沒關係 XDDD

Kim:

你前面說:每個服務的版本資訊 ServiceId=gtcafe.ooxx, Version=v1.0.0, 和部署資訊 InstanceId=deploy1, InstanceId=deploy2,這個看來是剛好完整搭配你們部署到不同 region 去的策略,很完整耶

Rick:

這是我規劃的整個核心想法之一,更嚴謹的是 Service Invocation 要做身份驗證,類似於 JWT 的機制。我連簽章做了 XD。

這整套設計想法,是可以開源的,比較像是一個開放規格的概念。因為所有 Microservice 的治理都會遇到這問題。目前我還沒看到有框架再談這些,最近有看到的是 Dapr 的 Service Invocation 有提到一點,只是從 function 角度切入,並沒有治理層面考慮。其中 Dapr 有規劃使用 SPIFFE, Secure Production Identity Framework for Everyone

大規模團隊,避免不了的服務交互,團隊 (人) 跟系統 (物) 就會有一定的關係,最後就是產品 (事),這個關係管理就是治理的問題,針對人跟物的管理,就是服務治理。

Kim:

沒錯 我們想的一樣

Rick:

你的提問,讓我梳理了很多想法,有空就把它放在 blog ~ 我會提到你喔 XDD

Kim:

好 沒問題


疏理對話中的問題

  • Q: 服務的定義是什麼?

我的定義:

  1. 提供獨立且完整的應用、或領域功能,這些功能可以以 Web Service 或者 Web UI 提供使用,
  2. 且能夠獨立部署、具備獨立運算資源 (Computing) 與資料 (Data / Storage)、網路隔離 (Network) 結構
  3. 與其他服務有清楚的邊界關係與依賴關係

基本上就是 Bezos 定義的那幾條 架構規範,詳細參閱:從 Jeff Bezos 與 Werner Vogels 學到的

一些問題:服務能不能隨意增加?增加之後的管理如何做?我有很真實的體驗,特別是 災難還原 時,攤開來一看就知道災難在哪。

  • Q: 對話提到的 每個版本,則會有多個部署 是什麼意思?

用一句話來說:Single Code Base,Multiple Deploy
其實 SaaS 的基礎。相關議題有 Multi-Tenancy Architecture、Marketplace Architecture。這大概要寫幾本書才講得完 XDD
常見例子就是 Wordpress 的一些 cloud providers,還有 CloudAMQP、MongoDB 的 altas 都算是。

  • Q: 服務通訊為什麼需要做簽章?

這個概念是參考 JWT 的,JWT 要解決的是 Web Service 的 Client / Server 之間資料傳輸的正確性問題。JWT 使用雜揍函示做資料正確性的驗證,確保資料沒有被串改。而我只是借用這個概念,應用在服務通訊時,做簡單的服務身份檢查,替代一般常用的 API Token 的方式。這樣的機制可以像 JWT 那樣,額外帶一些資訊,像是授權的條件在 payload 裡,除了可以檢查來源的服務身份是否正確,同時也可以做授權管理。

上述的服務通訊有個很重要的前提,這只的都是內部服務的通訊。


管理與治理

管理英文是 Management,治理則是 Governance,這兩個詞有什麼差異?

我有兩段筆記在講這兩個差異:

2020/09/04:

治理 (Governance)管理 (Management) 的差別?

很多人會聽我常講 治理 這個詞,反而很少講管理。我自己的定義是這樣:

治理是戰略層級,管理是戰術技巧。

治理談的是還沒開始,未來如何執行管理的方向、策略、政策。管理談的是已經開始,如何讓運作更順利的方法。

像是 分散式系統、尛服務架構必須具備的:服務治理,地方政府需要管理自己的行政工作,中央政府則需要有治理國家的方向。

2021/03/26:

地方首長治理行政區的第一個功課:

了解有哪一些行政區。

不要像某個市長候選人,競選過程,連有幾個行政區、每個區域大致的狀況、人口結構、產業特性、歷史因果、區域發展現況 …. 都搞不清楚,還說哪個區域晚上都黑壓壓 …

施政方向、計畫、預算,都會圍繞這些東西。

服務治理的第一課:

清楚精準列舉 現在有 哪一些服務,這些服務之間的結構、特性、職責、業務範圍、技術架構

所有的客戶、業務需求、開發、測試、維運 都跟這份清單,以及清單上每個東西的關係有關係。

管理一家公司的第一課:

對內搞清楚組織結構,知道哪些人是地頭蛇,然後就是了解這些人的厲害的關係,與財務結構。對外,搞清楚產業結構、客戶關係,列舉客戶大小、貢獻。

上面這段,其實都在談人、事、物的關係,也就是 看見怎樣的全貌 - 軟體開發的三體問題 提到的。


延伸閱讀




Comments