聊聊分散式架構的服務治理
大部分開發者聊到 微服務架構
、分散式系統
,都會談到 服務發現 (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,把這些接起來。
特別是有一些定義的問題:
- 大家對於 “Service” 的定義落差很大
- 大部分的 APP Team 對你說的 Service List 無感, 除非炸鍋. 最近半年內,有人跟我反應這問題幾次。
- Service Definition 的規範: Service list 還是要被管理,最後還是回到類似 DNS 的管理概念,需要有 FQDN 做全公司範圍的 Namespace 管理. 管理的前提要有清楚的定義,包含生命週期、資料結構、權責 … 等。
- 你說的版本管理 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: 服務的定義是什麼?
我的定義:
- 提供獨立且完整的應用、或領域功能,這些功能可以以 Web Service 或者 Web UI 提供使用,
- 且能夠獨立部署、具備獨立運算資源 (Computing) 與資料 (Data / Storage)、網路隔離 (Network) 結構
- 與其他服務有清楚的邊界關係與依賴關係
基本上就是 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,這兩個詞有什麼差異?
我有兩段筆記在講這兩個差異:
治理 (Governance)
跟管理 (Management)
的差別?很多人會聽我常講
治理
這個詞,反而很少講管理。我自己的定義是這樣:治理是戰略層級,管理是戰術技巧。
治理談的是還沒開始,未來如何執行管理的方向、策略、政策。管理談的是已經開始,如何讓運作更順利的方法。
像是 分散式系統、尛服務架構必須具備的:
服務治理
,地方政府需要管理自己的行政工作,中央政府則需要有治理國家的方向。
地方首長治理行政區的第一個功課:
了解有哪一些行政區。
不要像某個市長候選人,競選過程,連有幾個行政區、每個區域大致的狀況、人口結構、產業特性、歷史因果、區域發展現況 …. 都搞不清楚,還說哪個區域晚上都黑壓壓 …
施政方向、計畫、預算,都會圍繞這些東西。
服務治理的第一課:
先
清楚
且精準
的列舉
現在有哪一些服務
,這些服務之間的結構、特性、職責、業務範圍、技術架構所有的客戶、業務需求、開發、測試、維運 都跟這份清單,以及清單上每個東西的關係有關係。
管理一家公司的第一課:
對內搞清楚組織結構,知道哪些人是地頭蛇,然後就是了解這些人的厲害的關係,與財務結構。對外,搞清楚產業結構、客戶關係,列舉客戶大小、貢獻。
上面這段,其實都在談人、事、物的關係,也就是 看見怎樣的全貌 - 軟體開發的三體問題 提到的。
延伸閱讀
- Service Catalog
- 看見怎樣的全貌 - 軟體開發的三體問題
- 軟體交付的三體問題
- 摘要 Dapr 的設計與概念
- 從 Jeff Bezos 與 Werner Vogels 學到的
- 災難還原 - 實戰演練
- 系統發生異常時,第一時間如何快速止血?
- 表達與溝通的差異