Categories
程式開發

陌陌 Service Mesh 架構的探索與實踐


2016年,Service Mesh進入公眾視野之後一直保持著高速發展的狀態,目前已成為業內廣泛認可的下一代微服務架構,並且被CNCF列入構建容錯性好、易於管理與觀察的雲原生應用所依賴的關鍵技術。

2019年底,經過多年微服務架構實踐積累、對現有架構痛點總結分析以及多個階段的思考與評估後,陌陌正式啟動了Service Mesh落地項目MOA Mesh。本文將從原有微服務架構談起,詳細講述陌陌 Service Mesh架構的探索過程,希望能給業內同樣關注如何落地Service Mesh的技術人員提供參考。

陌陌微服務架構演進

2013年,陌陌架構團隊完成了微服務架構的研發與推廣,考慮到當時業內還沒有成熟的開源產品,陌陌自研了服務框架MOA(Momo service Oriented Architecture),並應用到了多條業務線,例如附近動態、直播、IM、短視頻等。

隨著業務的不斷增長,MOA完成了對自身能力與穩定性的驗證,發布服務2000+,註冊實例2萬+,全天調用量3500億,峰值時QPS達到600萬。

陌陌 Service Mesh 架構的探索與實踐 1

發展歷程

為了支撐大規模業務服務運行,MOA除了需要不斷完善自身之外,還需要與其他基礎架構產品協同運作,如:監控、異步、配置、日誌、分佈式跟踪、壓測等平台與系統。

回顧陌陌整個微服務體系的發展歷程,2011年還是在使用單體應用,2012年開始拆分系統,2013年自研了微服務框架MOA,2017年實現了應用容器化,2020年落地Service Mesh架構。

陌陌 Service Mesh 架構的探索與實踐 2

陌陌微服務體係發展歷程

多語言支持

陌陌服務端架構採用了PHP API + Java後端服務的多語言架構,以同時獲得PHP的開發效率與Java的高性能優勢。這也使得MOA從一開始就要應對跨語言調用帶來的挑戰。

MOA的核心組件是Java語言的SDK,在微服務體系中我們又進一步引入以下機制簡化其他語言SDK的開發工作

  • 能夠復用成熟Redis客戶端的Redis GET跨語言傳輸協議

  • 通過域名訪問、與普通服務調用方式一致的地址查詢服務Lookup

  • 由Java開發、以sidecar方式部署、作為入流量代理的MOA Proxy,支持非Java語言發布服務、接入整體微服務體系

整體架構

在融入相關基礎架構產品以及多語言支持機制後,MOA 1.0微服務體系已具備較為全面的服務治理能力。

MOA整體架構如下圖所示,其中MOA Watcher是中心化的健康檢測系統,同時MOA客戶端也具備自動容錯機制;並行調用代理是為了支持PHP語言實現並行調用的中心化出流量代理。

陌陌 Service Mesh 架構的探索與實踐 3

架構痛點與Service Mesh

架構痛點分析

在業務規模不斷擴大、微服務架構持續演進的過程中,存在一些始終無法徹底得到解決的問題,它們可以統一歸納為“服務治理能力滯後”問題。

非Java應用能力滯後

原有架構中採取了很多簡化開發多語言SDK的機制,但在中間件團隊以Java工程師為主導的情況下,其他語言SDK的迭代速度還是會遠落後於Java SDK,導致其他語言SDK缺少很多關鍵的功能,並且無法快速完成修復與補充。

Java應用能力滯後

Java SDK具備最完善的服務治理能力,但當Java應用的數量達到數千規模,SDK的升級會成為極其困難的工作,使新開發的功能同樣無法快速在每個應用上得以運用。即使在一些緊急情況下集中進行推廣,每個應用修改版本依賴、重新發布的過程也會耗費業務團隊和基礎架構團隊大量的時間精力,對整體業務迭代效率產生負面影響。

滯後問題危害

服務治理能力滯後問題使整體的微服務架構無法實現統一。缺失的能力會使應用的穩定性受損,甚至引發故障。在進行重大架構變更時,缺失以及無法快速補充的能力會成為理想方案的阻礙,從而被迫選擇其他存在缺陷的方案。

引入Service Mesh

Service Mesh將服務框架核心邏輯剝離到本地代理進程的方式,能夠使Java SDK升級和多語言SDK重複開發問題得到徹底解決。但是否應該引入這項全新的架構方案,還需要對以下問題進行深入、全面的評估:

  • 是否足夠成熟、不對穩定性造成影響

  • 是否有其他方案能夠達成相同的目標

  • 是否投入有限、可以接受的成本

  • 是否能真正解決問題、帶來期望的價值

經過慎重的思考,我們決定引入Service Mesh來解決原有架構的痛點。

觀察階段

對於一項新技術方案我們沒有額外的人力去“試錯”。這一階段我們首先對Service Mesh的發展保持密切關注,同時也在等待公司內部的一些基礎設施成熟,如:應用容器化部署推進、日誌監控類Agent方案日趨完善等。

試驗階段

對現有問題嘗試通過其他方案解決。例如非Java語言SDK最急需的是流量調度能力,我們嘗試採用無流量代理Agent的方案,僅將路由選址機制下沉到Agent。但發現業務進程與Agent之間存在復雜的交互邏輯,並且無法做到徹底解耦。

評估階段

對Service Mesh方案進行全面評估,包括調用耗時增長問題、服務器成本、人力投入等。確保方案帶來的成本及影響在可接受範圍內。

啟動階段

在現有業務規模下,提升業務團隊開發效率、減輕業務團隊負擔是基礎架構部門的首要工作目標。保持服務治理能力高速迭代、並且使業務團隊從SDK升級的工作中解放出來,是我們決定引入Service Mesh方案時最關注的價值。

陌陌Service Mesh架構實踐

業內方案調研

Istio

目前最具影響力的開源產品Istio提供了一套完整、具體的解決方案,包括代理流量的數據平面、管理代理層的各個控制平面組件等,各公司的落地方案幾乎都會參考Istio的設計。但Istio目前還是一個在高速演進中的產品,與k8s的某些機制綁定、存在性能瓶頸等問題使得很多公司並沒有直接使用Istio。

陌陌 Service Mesh 架構的探索與實踐 4

螞蟻金服

螞蟻金服選擇用Go語言自研數據平面產品SOFA MOSN,並在過去的一年完成了大規模的落地實踐驗證。其中的平滑升級機制取得了非常理想的效果,值得作為數據平面追求的目標。自研的控制平面SOFA Mesh目前在與Istio進行融合。

陌陌 Service Mesh 架構的探索與實踐 5

美團

美團基於Istio的數據平面產品Envoy進行了二次開發,以支持與現有內部系統融合和存量服務接入。美團原有的服務框架產品OCTO具備非常完善的服務治理功能,這部分經驗被運用於自研的控制平面之中。

陌陌 Service Mesh 架構的探索與實踐 6

陌陌方案選型

從各個公司的方案來看,使用開源產品、二次開發、自研方向都有實踐的案例。如果是構建一個全新的應用,採用開源產品方案、持續跟進社區是比較理想的選擇。陌陌當前的目標是使存量服務升級為Service Mesh架構,最終採用了數據平面與控制平面均自研的方案,並使用Java語言來開發數據平面代理流量的Agent。在方案選型過程中我們重點考慮以下三方面的因素

與現有架構的兼容性

MOA框架使用的是私有協議,而非標準的HTTP、gRPC協議,直接使用開源的數據平面產品需要進行較多的適配改造;同時接入其他內部系統也需要進行大量改造。

現階段的關鍵需求

當前架構的痛點是SDK升級與跨語言,而不是缺少控制平面功能;直接引入開源控制平面產品會大幅增加方案的複雜度,並且社區的控制平面產品還在逐步完善的過程中。

技術儲備與原則類因素

出於技術儲備、人才儲備等原因暫不希望技術體系內引入Go語言;公司內開發服務端應用最成熟的是Java語言;自研MOA框架積累了較為豐富的經驗。

整體架構

現階段我們關注的核心收益均由數據平面產生,因此整體方案中將著重進行數據平面Agent的建設。在控制平面方案中,通過增加一層輕量的Pilot Proxy實現數據平面Agent與其他內部系統之間的解耦。控制平面優先採用Istio的標準協議(如xDS、MCP等)實現組件間的通信,為後續逐步向社區靠攏提供可能。基於Service Mesh的MOA 2.0整體架構如下圖所示

陌陌 Service Mesh 架構的探索與實踐 7

數據平面架構方案

數據平面是與業務進程直接交互的層面,關係到業務團隊的直觀體驗與應用整體的穩定性。在設計數據平面方案時,我們重點關注平滑升級、Agent容災、代理性能三方面的內容。

平滑升級

為了實現Agent迭代升級過程無需業務團隊參與,該過程對業務開發人員必須是無感知的,“平滑升級”流程需要滿足

  • 業務進程不重啟

  • 業務進程的流量保持不變

常規的流量切換方案,需要藉助新的Agent IP或端口、經過複雜的流量調度過程,才能接近實現業務進程流量保持不變。我們選擇採用業務感知更為友好的“FD遷移方案”。通過調用Linux操作系統的sendmsg / recvmsg接口,舊進程能夠將所持有連接的的FD(文件描述符)發送給新進程,新進程能夠將接收的FD還原成連接繼續進行讀寫操作。

Java本身的JDK並未暴露操作系統的底層接口,需要通過JNI的方式進行調用。 Java的網絡框架Netty已經實現了相關接口的封裝,在Netty提供的Java API基礎上開發即可實現FD遷移的相關機制。

陌陌 Service Mesh 架構的探索與實踐 8

Agent容災

引入數據平面轉發流量後,整體架構會變得更加複雜。在設計針對Agent的容災方案時,遵循的原則是簡單、依賴盡可能少的資源。

對於大多數服務類型的應用,Agent代理的出流量均由入流量產生。此時可藉助微服務體係原有的健康檢測機制進行容災,在Agent發生異常時摘除實例流量,使整個服務不再受異常Agent的影響。

對於少數Agent僅代理出流量的場景,在Agent發生異常時SDK可以將流量切換至本應用的其他Agent。由於同應用內的Agent具有相同的配置、資源、鑑權要求,這一切換過程具有最小的切換代價和最高的穩定性。

陌陌 Service Mesh 架構的探索與實踐 9

代理性能

在眾多影響Agent流量代理性能的因素中,通信協議是最關鍵的環節之一。 MOA原有的協議不支持可擴展的header字段,在轉發請求時需要decode整個Request的字節數據才能獲得服務名等路由信息。這種情況下需要新增一種傳輸協議,使請求轉發時能夠避免解析Request Body產生的開銷。新協議同時需要對原Redis GET協議不支持單連接並行處理請求的問題進行連接復用優化,使代理轉發性能達到最優。

陌陌 Service Mesh 架構的探索與實踐 10

展望

陌陌的Service Mesh架構實踐仍處於起步階段。當前數據平面已完成研發,開始逐步進行線上服務的灰度驗證。接下來我們將進一步完成控制平面建設、完善數據平面功能、解決線上業務大規模推廣中遇到的問題。我們計劃將每一階段的經驗和感悟都分享出來與業內進行廣泛的交流,敬請期待未來持續更新的內容。

作者介紹:

高飛航,陌陌中間件架構師,在微服務、多機房架構及中間件產品領域有較為深入的研究,當前關注Service Mesh、雲原生等技術方向。

陌陌基礎平台團隊持續招聘基礎中間件高級架構師、資深Java工程師等崗位,團隊致力於為公司及子公司等提供完善的基礎架構能力交付,包括微服務治理平台、配置中心、監控平台、消息平台、存儲中間件、IM通用解決方案等技術領域,歡迎有興趣的同學加入我們一起建造穩定、可靠的基礎架構設施,簡歷投遞方式:[email protected]