文章整理:加米谷大數據
Jupiter 是鬥魚開源的,面向服務治理的 Golang 微服務框架,以開發效率和治理效率為核心目標,從統一開發規範、完善監控埋點、降低開發難度等多個維度來幫助 Gopher 開發高性能、高可靠性的微服務框架。
Jupiter 在鬥魚內部經過三年打磨、幾百個服務的線上驗證,在多種應用場景中適配、歷經多次基礎架構迭代,有效地保障了服務應用的快速迭代、精確監控,並在異地多活、容器雲、混沌工程等基礎建設中,支撐服務的平滑遷移、平穩變更。近期,Jupiter Go v0.5.0 正式發布,與之同步發布的還有治理平臺 Juno。兩者相得益彰,幫助開發者快速落地、並具備服務治理能力的微服務架構。我們致力於將 Go 微服務框架標準化,統一錯誤碼、日誌、監控、註冊、流控的 Schema。做到微服務的各個模塊可觀測、可治理,管理微服務研發側的全套生命周期。以下是 Jupiter 的架構圖。
微服務基礎框架
現代微服務架構是分布式的,業務邏輯被拆分到不同的服務中,服務之間通過 RPC 相互調用。隨著業務規模的增大,服務的數量也隨之增加,當增加到一定程度的時候,開發和運維效率將面臨嚴重挑戰。
鬥魚 Web 服務在服務化過程中為應對這種挑戰,逐步形成了以 Jupiter 為核心的基礎框架和以 Juno 為核心的治理平臺。
Jupiter 是作為面向服務治理的微服務基礎框架,有四個核心關注點:
開發效率: 提升開發效率、加速軟體生命周期的迭代。治理效率: 提升治理效率,實現規模化治理。多場景應用: 識別通用場景,形成公共知識,持續提升團隊開發效率。演進式架構: 保證服務在自建機房、容器雲、網格化等基礎架構變更和基礎設施變更過程中的平滑遷移。開發效率
開發效率是 Web 框架的核心關注點,好的 Web 框架融合了代碼規範、最佳實踐和安全編碼,並能顯著提高編碼效率。如果是自研的框架,還承擔著把組織內部的知識,進行抽象和提取,形成公共知識的責任。
同時,Golang 作為一門「新」語言,生態相對也較「新」,實際使用還將面臨一些「額外」風險:
開源類庫的質量和維護力度參差不齊,如果有 bug 或者不兼容問題,其修復難度較大。Golang 去中心化的依賴管理會導致類庫管理困難,開發人員可以隨意「引入」或「升降級」依賴庫。不同類庫的代碼風格差異大,有一定使用成本。Golang 歷經了多種包管理方式,對國內的開發者而言,儼然一部血淚史。目前 gomod 大有改善,但仍有個別老舊類庫存在問題。Jupiter 是伴隨鬥魚服務化一步步實踐而來,經歷了 go1.7 到 go1.14 既平滑(完美向前兼容)又劇烈(生態、依賴管理)的成長。針對業務的開發效率以及「額外」風險,Jupiter 有一些基本的認識:
以 monorepo 的方式整合核心框架、自研類庫並包裝第三方類庫。長期看,這將極大減少維護成本。利用語言機制如 type alias/type embedding 等,封裝常用的第三方類庫,儘量減少直接引用第三方類庫。這提供了一種緩衝機制,避免依賴被隨意「升降級」,第三方 bug 也可以被方便管控。通過包裝,一些關鍵類庫萬不得已的時候可以切到自研,也可以由自研切換到開源,降低維護成本。統一所有包的使用方式,包括配置驅動、統一錯誤碼、統一日誌埋點、指標埋點等,減少開發人員心智負擔。當然,上述很多問題不能僅僅依賴於基礎框架來解決,並且隨著 Golang 語言和生態的發展,一些問題也在不斷緩解。但核心的需求還在,即通過整合基礎框架,降低風險,提高效率。
除了針對主要開發環境的效率提升外,Jupiter 針對調試、測試、CI 流程等方面也做了一些工作,以提高整個軟體周期的效率。
治理效率
治理效率是微服務架構的關鍵需求。微服務架構中,應用數總是不斷上升,人均應用維護數增加到一定數目以後,維護效率將大幅度下降。如果碰到突發事件,將產生嚴重後果。因此,微服務架構非常強調服務治理能力和應用管理能力。一般來說,微服務治理包括:
服務註冊與發現: 服務註冊、負載均衡等可觀測性: 拓撲關係、指標、日誌、鏈路等流量管理: 流量特徵識別、流量導向等,以及基於此的灰度、藍綠髮布、A/B Test 等細分應用安全策略: 訪問控制、限流熔斷等生命周期: 發布、下線管理,版本控制等微服務治理是一項基礎能力,需要代碼規範、治理平臺、基礎框架甚至組織架構等多個方面協作,才能達到比較好的效果。
我們近期還會將治理平臺 juno 開源部分微服務治理能力,未來還將整理和開源更多的治理能力,並與社區共建,進一步完善微服務治理。這部分,我們將在單獨的文檔中進行更詳細說明。
在基礎框架的部分,我們認為基礎框架是溝通業務與治理平臺的關鍵,一定程度上也定義了服務治理流程。在 Jupiter 中,針對服務治理,有幾個關鍵點:
增強核心模塊可觀測性:完善的日誌、指標、鏈路埋點,並形成規範,從而實現報表、報警直出。統一錯誤碼: 規範的錯誤碼和錯誤收斂機制,能夠極大的提升錯誤定位和排查速度。攔截器支持: 針對 http/grpc 的 server/client 以及 redis/mysql/mongo/rocketmq 等 IO,全部支持攔截器機制,以進一步支持更豐富的治理策略。安全策略內置: 主要模塊內置限流熔斷、訪問控制、慢查詢監測等安全策略。流量路由和管理: 提供多種負載均衡和流量路由策略,以及針對 A/B Test、影子流量等細分場景的流量策略。多應用場景
支持多應用場景前,需要準確的識別應用場景,而識別的過程就是一個規範代碼、探索實踐的過程。應用場景的定義可以很寬泛,這裡舉幾個例子簡單說明:
緩存策略。緩存的策略有很多種,在 Web 開發領域也經常使用。我們注意到業務實現中,經常會有數據過期時,一個請求穿透、多個請求原地 block 的場景。通過引入滑動窗口和半衰期,讓一個請求穿透、多個請求正常返回,從而實現更高效的緩存策略。與 Java Dubbo 流量互通。dubbo 支持 gRPC 協議,因此在協議層,dubbo 與 grpc-go 是可以流量互通的。Jupiter 通過增加一個基於接口 (dubbo 的默認註冊方式) 的服務註冊鍵,從而實現服務註冊與發現層面上的流量互通。類似的例子在 Jupiter 中還有很多,如任務編排、流程編排、redis 的並發 pipeline、在線壓測的 mysql 影子流量等。
應用場景的識別是形成公共知識、加速團隊開發效率的重要手段。
演進式架構
Web 開發和運維技術在不斷的發展,短短幾年已湧現出了非常多的計算形態,如雲計算、邊緣計算、容器化、網格化、Serverless 等。服務保障技術方面,異地多活、混沌工程也在不斷發展。語言棧方面,很多公司也在從早期單一的 PHP、Java 棧擴大到多語言棧並存的局面,特別是近年來 Golang 因在容器化和運維效率上的優勢,越來越多的被應用到 Web 服務開發。但每次技術迭代,享受效率提升的同時,也在不斷經歷應用改造和遷移的痛苦。
從應用的角度來看,面對的是一個不斷變化的外部環境,新的問題不斷產生。以鬥魚 Web 服務部為例,可以通過一個時間線管中窺豹:
應用開始服務化: 這個階段開始構建大量的基礎治理平臺,包括發布中心、監控中心、註冊中心及各個管理細分平臺。 同時,一些新的基礎設施開始引入,如 etcd,prometheus、jaeger 等。語言棧從單一的 PHP 擴展為 Golang、Java、PHP 的多語言棧。API 規範、服務互通在這個階段凸顯。多機房建設: 流量管控、服務質量、安全策略的要求凸顯。容器化: 傳統基於 IP/Port 的治理方式、流量管理和分發、服務監控需要做出相應改變。Service Mesh: 基於 SDK 的服務註冊、發現,監控需要適配。總體上,基礎架構的變更將對整個治理體系產生影響,特別是治理平臺。正視變化,並前瞻性和針對性的優化,將有助於減少外部環境變化對業務邏輯的影響,並享受整個生態進步帶來的效率提升。
治理後臺展示
關於治理平臺開源 Juno,這裡放上幾張截圖供大家了解。