從 0 開始構建一套微服務治理平臺
作者 | 尚鵬飛
策劃 | 蔡芳芳
近年來,FreeWheel 核心業務開發團隊致力於將傳統單體 Rails 應用,向分佈式微服務架構遷移,以適應越來越複雜的業務場景和系統性能的提升。隨着微服務規模的不斷增長,一些新問題也隨之產生。其中,如何對這些業務服務進行有效的治理和維護,對業務狀態進行監控,甚至於線上調試變得尤爲重要。業務服務治理平臺(business service management platform),是我們爲應對這一挑戰做出的選擇。本文將詳細解析 FreeWheel 核心業務開發團隊構建的服務治理平臺。
1 爲什麼需要服務治理平臺
隨着 Rails 單體應用向分佈式微服務架構遷移的深入,面向不同業務和層次的微服務如雨後春筍般誕生,微服務集羣的規模迅速增長。架構遷移讓我們可以把業務重新梳理、聚合和解藕,不同的微服務可以聚焦自身業務,自成體系進行維護,減少了對其他業務的影響,增加了系統整體的可擴展性。
但同時,這也導致有越來越多的微服務需要治理,原本只需要對一個單體應用進行監控管理,如今卻需要對幾十個甚至上百個微服務進行管理。
另一方面,分佈式架構本身也會引入一些在單體應用時不存在的問題,例如分佈式事務、消息等,對這些方面,我們也缺少相應的治理平臺。因此,在我們的分佈式微服務實踐過程中,經常要面對以下這些問題:
-
微服務在出錯或響應慢時,如何能進行簡單快速的調試,以便了解是微服務本身的問題,還是所依賴的服務有問題?
-
相比於單體應用,分佈式系統更容易引入數據不一致,如何對這樣的數據進行監控?
-
在基於異步消息的業務中,某個主題的業務沒能正常完成,是生產者沒有把消息發出來?還是消費者沒有接收到消息?
-
爲什麼數據庫已經更新的數據遲遲沒有生效?緩存數據何時過期?
-
我們有哪些後臺任務正在執行?執行的排期如何?執行失敗的原因是什麼?
-
……
微服務的部署層面,我們可以通過業界雲原生的解決方案來實現,而這些業務層面的問題卻很難找到一個公共的解決方案或治理入口,因爲這往往是跟具體的業務場景深度綁定的。不同的微服務業務場景和功能不同,但基本都遵從類似的開發實踐,使用相同的基礎組件,這使得我們對微服務進行治理成爲可能。
2 業務微服務治理平臺實踐
-
業務服務治理平臺在某些功能上,需要和 FreeWheel 特有的業務深度綁定。
-
避免與 FreeWheel 已有的 PQM(FreeWheel 監控平臺)、FOC(FreeWheel 運維中心)等模塊功能重合。
-
平臺應輕量級,能快速迭代開發。當有新需求出現時,可以更快更好地對平臺進行橫向擴展。
技術選型與架構
針對服務平臺 Falcon 的構建,我們從以下幾個方面進行了技術對比和選型:
根據以上對比,基於對治理平臺快速開發、穩定運行的要求,我們最終選用 React+Nodejs+Mysql+AWS RDS 的組合來進行開發構建。
按照 FreeWheel 今天的業務場景需求,我們的治理平臺將包括四個主要的部分:Falcon 前端、Falcon 後端、數據庫和 Redis。
爲了與現有的服務集羣進行整合,我們需要將治理平臺的各模塊部署在 AWS 集羣中:
其中:
-
Falcon 前端主要提供所有的 Web 前端資源和邏輯,它是獨立於後端進行開發和部署的,實現了前後端的分離解耦。
-
Falcon 後端是整個平臺的後端服務器,負責平臺的所有業務邏輯。同時,它需要和集羣中的業務微服務和公共組件進行通信交互。
-
數據庫用於存儲平臺自身的數據,例如登錄用戶的信息、採集到的業務數據等。
-
Redis 模塊是爲了實現定時任務等功能點所引入的模塊。爲了儘量減少對線上微服務的影響,我們沒有使用集羣中業務微服務所使用的 Redis,而是重新部署了一個單獨的 Redis。
我們將 Falcon 前端 /Falcon 後端 /Redis 打包,以 Kubernetes Pod 的形式運行部署,和 FreeWheel 的業務微服務部署在同一個 AWS EKS 集羣中,而數據庫使用了 AWS RDS 服務來支持。我們對 Falcon 前端 /Falcon 後端 / 數據庫暴露了 VIP,FreeWheel 內網進來的請求,會先經過 AWS ALB,轉發到服務網格 Ingress Gateway,最後打到 Falcon 對應的 Pod 或數據庫。
平臺運行工作流
當 Falcon 被部署運行使用時,會經歷以下過程:
-
部署之後,Falcon 後端開啓消費者監聽 Kafka 消息
-
Falcon 後端加載數據監控配置進 Redis,開啓任務調度
-
用戶訪問 VIP 地址, 請求被路由到 Falcon 前端 Pod,Falcon 前端返回 JS 資源
-
瀏覽器加載並渲染前端資源,進入登錄頁面
-
用戶輸入 LDAP 用戶名 / 密碼,請求路由到 Falcon 後端,Falcon 後端驗證登錄,存儲登錄信息進 session 和數據庫
-
用戶在平臺界面操作,請求路由到 Falcon 後端,將操作數據存儲,或實時調用業務微服務,完成對應操作
平臺提供的功能模塊
今天 Falcon 針對於業務團隊的痛點實現了許多功能模塊,還有一些功能模塊正在探索和開發中,下圖是 Falcon 的導航首頁。
接下來,本文會圍繞 Falcon 的這些功能模塊進行介紹:登錄驗證,數據監控模塊,後臺任務模塊,異步消息模塊,業務緩存模塊,線上調試模塊,用戶管理模塊和使用記錄模塊。
準備工作 - 登錄驗證
出於系統平臺安全性的考慮,我們限定了只有在 FreeWheel 內網纔可以訪問 Falcon 平臺。平臺的使用用戶限定在 FreeWheel 的工程師團隊,而 FreeWheel 內部員工使用 LDAP 來做賬號的統一登錄認證,因此 Falcon 後端也集成了 LDAP 對登錄用戶認證。在用戶首次登錄時,Falcon 會將該用戶同步存儲在數據庫中,以便之後爲其配置在 Falcon 平臺的用戶權限。
數據監控
數據監控模塊旨在監控異常的業務數據。在從 Rails 單體應用遷移到分佈式微服務後,很多數據的增刪改不再由原來一個數據庫事務來完成,而是變成了多個微服務多個數據庫事務來進行數據更新,因而很難保證不同微服務間的數據強一致。一個簡單快速的方案就是對業務不一致的數據進行監控,Falcon 提供了這樣一個入口進行髒數據的監控和報警,用戶可以通過提供一段 SQL 語句,或者是微服務實現的一個接口,來達到對特定數據的監控目的。
如上圖所示,Falcon 後端在啓動完成後,從數據庫加載數據監控設置,初始化基於 Redis 的任務隊列。任務隊列中的任務根據設置好的排期,定時調用 Handler 執行 SQL 或調用接口,將執行結果寫會到數據庫。同時將執行結果與用戶設置的參數進行比較,一旦發現滿足髒數據條件,即進行報警通知訂閱者。今天 Falcon 提供了 Email 和 Slack 兩種方式進行報警通知。用戶可以實時更改監控設置,Falcon 後端會將用戶的實時更改持久化,並更新任務隊列即時生效。
後臺任務
後臺任務一般分爲定時任務和按需任務。相信大部分的系統平臺都有與自身業務相關的後臺任務,FreeWheel 也不例外。
針對這一痛點,我們在 Falcon 中構建了後臺任務的可視化模塊,提供 5 個方面的內容:Worker Pool、Queue、Scheduled Job、Retry Job、Dead Job。用戶可以查看到正在執行的任務有哪些,隊列中已有哪些任務,將要執行的定時任務分別安排在了什麼時間,重新過的任務是哪些,哪些任務執行失敗了等等。例如下圖中展示了 Inventory Service 中每 10 秒執行一次的 default_check_alive 任務的排期情況。
特別的,我們可能更關注於哪些任務執行失敗了,以及失敗原因,因此我們把失敗任務的諸如參數、錯誤內容等詳細信息展示出來,並提供了重試功能,以便在工程師在排查完錯誤原因後,可以手動觸發重新執行任務。如下圖展示了 Order Service 最近執行失敗的任務、任務參數、失敗原因等等。
異步消息
隨着微服務集羣規模越來越龐大,業務越來越複雜,異步消息機制也被越來越廣泛地應用,微服務在很多業務場景中都需要發送 / 接收異步消息。從工程師的角度,我們很希望能實時得知消息是否被成功發送到 Kafka,發送的消息內容是否是我們所期望的。以往我們只能通過查看日誌的方式來獲知消息的發送情況,這對工程師是非常不友好的。在這個模塊,我們通過新加消費者監聽消息的方式,並將監聽消息展示,實現了 Kafka 業務消息的可視化。
業務緩存
爲了提升微服務的處理能力和響應性能,減小業務層對數據庫的壓力,我們會在領域微服務中加入緩存,將常用不易變的數據放到緩存中。每次有新的請求過來,先查詢緩存,如果有數據並不過期,則直接讀取返回。類似於後臺任務模塊和異步消息模塊的問題,緩存中存了什麼,有效期多久,何時進行的更新,在微服務運行時我們是無從得知的。
一個常見的場景是,數據庫中的數據更新了,卻不能很清楚地知道數據何時能生效,在定位問題時很容易導致判斷錯誤。在這個模塊中,我們將緩存數據進行了可視化展示,提供搜索功能以針對特定的 key 進行查詢,用戶可以很清楚地看到有哪些數據被緩存,數據量多大,到期時間等等。如下圖展示了 Metadata Service 中當前緩存的業務數據情況。
線上調試
領域微服務的業務中,往往需要依賴於第三方的服務,而在生產環境中這些第三方服務發生問題時,我們很難快速地從微服務的角度進行問題定位。比如下層服務響應慢,微服務對外的表現也是響應慢,但很難確定是微服務本身操作數據庫慢,還是調用下游服務響應慢。不同的微服務可以根據自己的業務情況,實現自己的調試接口,提供調試信息。線上調試模塊提供了調試入口,將調試接口集成到平臺調試模塊,用戶就可以在平臺手動觸發,查看整個鏈路的執行情況。這在發生線上問題時,能幫助工程師快速定位出錯原因,節約處理時間。
以 Advertising 模塊爲例,今天它主要依賴於 Feedback/Counter/Conflict Detection/Presto/S3 等服務,我們針對於這些依賴都接入了特定的調試接口。平臺本身提供了快速接入其他接口的代碼模板,在有新的需求出現時能快速擴展。
用戶管理
Falcon 平臺的功能和架構定位,決定了它的重要性和影響程度遠高於微服務。儘管平臺致力於實現對於業務有保護性質的功能,但仍有必要對登錄使用該平臺的用戶進行管理,以避免發生誤操作造成嚴重影響。我們採用了通用的用戶 - 角色 - 權限模式來進行用戶的管理,每個功能模塊都定義了讀寫權限,細化到微服務,在此之上按團隊劃分配置了工程師角色,只需要給不同用戶以相應的角色,即對該用戶在平臺的操作權限進行了控制。如下圖是給一個 Advertising 團隊工程師的權限。
使用記錄
作爲平臺系統完整性的一部分,也爲了更好地追蹤平臺上的設置更改,我們實現了使用記錄模塊,以記錄在該平臺上發生的所有更新操作。由於平臺本身沒有特別的複雜業務,同時更新不會特別頻繁,因而在記使用記錄時我們選擇記錄使用全量,而非變量,即當某個對象發生變化時,都將原始對象的快照進行全量備份。下圖是某次更改設置的新值與舊值的對比,通過記錄全量,我們能很清楚地看到某一時刻整個數據的狀態,也能很容易地看到那些字段發生了變化。
3 結語
Falcon 作爲 FreeWheel 核心業務開發團隊從 0 構建的一套微服務治理平臺,提供了諸如數據監控、異步消息等功能模塊,幫助工程師解決了很多在分佈式微服務架構時期所面臨的業務治理或監控痛點。目前這個平臺只提供了一些對工程師而言最急切的功能,很多地方還有待進一步提升,未來我們會從以下幾個方面進行持續進行工作:
-
對已有的功能進行持續優化完善,確保平臺穩定可靠
-
探索對分佈式事務的集成與支持,以對異常分佈式事務進行控制
-
提供配置中心功能,集中管理業務微服務配置
-
集成報警,讓工程師可以簡便快捷進行預警配置
-
支持功能快速擴展,當有新的功能需求時可以快速集成
對於微服務治理我們還是新人,未來我們仍將在這條路上持續學習、深入探索。
作者介紹
尚鵬飛,FreeWheel 高級研發工程師,任職於 FreeWheel 核心業務開發團隊,擅於解決後端業務系統的複雜問題,有豐富的開發經驗和敏捷團隊管理經驗,熱衷於新技術的探索與分享,目前致力於 Golang 微服務和系統重構相關工作。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/0xf0Gd0NAruTzRWC5oVjkg