Categories
程式開發

Apache Dubbo的愛奇藝之旅


Apache Dubbo 簡單介紹

Apache Dubbo是一款開源的RPC(Remote Procedure Call,遠程過程調用)框架,其提供了簡單易用、高性能的RPC能力、靈活可控的擴展、強大的服務治理、完善的開源生態支持,目前已有Java、Go、JS、Python等多個語言支持。

Apache Dubbo更是一款服務治理框架,其在服務治理層面提供了多種靜態以及動態路由配置、集群容錯、可視化運維、監控、流量調度等功能。如下圖所示:

Apache Dubbo的愛奇藝之旅 1

Dubbo基本架構

更詳盡的信息可以參考Dubbo官方網站:http://dubbo.apache.org/zh-cn/docs/user/quick-start.html

愛奇藝在Dubbo上的實踐

愛奇藝從2019年開始正式引入Dubbo,從引入之初,我們即確定了基於Dubbo強大的SPI(Service Provider Interface,服務發現機制)機制定制公司內部插件的技術路線,目前來看,這套機制可以滿足我們對Dubbo的定制化需求。

第一個版本主要提供了對公司基礎設施的適配和兼容和容器運行環境的適配、以及配合愛奇藝的監控系統進行一些基礎的埋點。這樣對後續各個業務團隊能夠更高效地使用Dubbo框架開發業務應用。該版本發布後我們收集到了業務方的很多積極反饋和需求,這也堅定了我們想要去做好Dubbo和推廣Dubbo的決心。

以下是針對愛奇藝註冊中心、配置中心及元數據中心的適配:

1.註冊中心方面,考慮到歷史原因和維護成本,我們初期依舊選擇了之前內部廣泛使用的Zookeeper作為註冊中心,並通過集群名稱的方式讓用戶進行訪問(類似iqiyi-zk://idc1-cluster ),其目的主要是簡化用戶配置,並方便之後對Zookeeper集群進行透明運維。
2.配置中心方面2.7.x版本中很大的改進就是對於配置中心功能的加強,配置中心不再只是提供全局Dubbo啟動配置的一個數據庫,而是真正地利用了配置中心的推送能力進行,包括服務治理、運行時動態配置。
3. 元數據中心也是2.7.x版本中引進的新特性,其主要目的是將一些與調用無關的數據,例如元數據、方法信息等與註冊中心的URL分開存儲,有效精簡URL,減輕註冊中心推送和存儲的負擔。我們選擇了官方推薦的Redis作為存儲中心。

不久後,我們發布了第二個版本,主要是對站點管理平台的一些改造(下圖部分敏感信息打碼)。

Apache Dubbo的愛奇藝之旅 2

我們嘗試新版本的Dubbo Admin站點的一些功能集成到了內部管理平台上,並且與之前的站點進行了整合,目前主要功能包括實例新消息可視化、監控展示、基礎報警訂閱、服務接口查看、服務在線測試和治理配置下發。

第三個版本著重對Dubbo的可用性、RPC調用的效率以及安全性方面進行了加強。

我們在Dubbo上做的工作總結如下表:

1 基礎設施維護
內部Dubbo擴展:使用別名方式進行連接,方便運維管理
開源Dubbo版本:需自行申請維護,不便於運維

2 部署環境
內部Dubbo擴展:任意環境部署,無需額外配置
開源Dubbo版本:容器暴露的是虛擬ip和端口,需要自行改造註冊發現、或者配置ip信息

3 服務治理和監控
內部Dubbo擴展
1)集成微服務平台
2)重要指標採集,對接內部監控平台,可視化查詢,自定義指標查詢,重要指標報警訂閱
3)服務治理規則、服務壓測、服務在線測試

4 可用性加強
內部Dubbo擴展
1)不健康實例剔除
2)服務級別熔斷、降級、限流
開源Dubbo版本:需自行開發

5 多地部署
內部Dubbo擴展:同區域優先路由,無需關心部署環境
開源Dubbo版本:需自行開發

6 安全性
內部Dubbo擴展:提供AK/SK鑑權認證
開源Dubbo版本:自有鑑權機制,安全性低

Apache Dubbo 的優化

以下主要在可用性、多地部署調用優化以及安全性幾個方面的加強進行詳細地介紹。

提升可用性

可用性方面我們通過如下兩個維度加強:

  • 實例級別可用性
  • 服務級別的可用性

實例級別可用性

在生產實踐中發現,如果僅僅依賴註冊中心進行健康檢查可能無法剔除所有的非健康實例。例如,在一個具體的場景中,某業務團隊線上頻繁出現超時,最終排查發現這是因為部署的某個容器磁盤寫滿,導致該實例處理請求時一直阻塞在寫日誌刷盤的過程,以至於客戶端請求超時。對於這種情況,需要在框架中提供一種策略,使得我們能夠發現這些非健康實例,即在對某個實例的請求頻繁出錯或者超時的情況下,臨時屏蔽掉該實例,優先調用其他健康的實例,並定期探測,以便於在該實例恢復到健康狀態之後,能及時把該實例加入到負載均衡的列表中。

Apache Dubbo的愛奇藝之旅 3

因為Dubbo是典型的富客戶端模型,即負載均衡、路由等功能都是在客戶端SDK中集成,客戶端無法直接獲取到服務端的整體監控指標,如QPS/響應延時/錯誤率等。所以,我們用了客戶端幾個最基本的並且能方便採集的指標作為判斷的依據,例如請求錯誤比例、請求超時比例、請求未返回比例。考慮到擴展性,我們也提供了SPI機制,方便業務自己去決定怎樣的實例是健康的。 SPI接口如下:

Apache Dubbo的愛奇藝之旅 4

具體使用方式是通過parameters開啟該功能並且指定健康監測策略,以註解方式舉例:

Apache Dubbo的愛奇藝之旅 5

服務級別可用性

要保障微服務應用穩定性運行,熔斷和限流也是必要的保護機制。在某個客戶端過多地佔用服務端資源,我們需要通過動態配置方法限制其調用數;在依賴的第三方服務發生故障時,為了不級聯影響到其他核心功能的正常使用,對這類服務進行快速失敗或者是觸發降級功能。

在進行大量調研之後,我們最終選擇開源Sentinel,並在其之上進行熔斷降級、限流等功能的開發,並且加強了Sentinel Apache Dubbo Adapter插件的功能,增加了對Dubbo異步的支持、支持基於group /version等服務端屬性進行細粒度控制等。這部分代碼已經貢獻至Sentinel社區(已合併),歡迎大家使用。

插件地址:https://github.com/alibaba/Sentinel/tree/master/sentinel-adapter/sentinel-apache-dubbo-adapter

提升RPC效率

為了避免機房級別故障,會將服務的實例冗餘並分散部署在不同的機房甚至地區。但在一般情況下,跨地區的訪問延時很高,如從北京到上海的請求,僅網絡延時就將近30ms。在這樣的背景下,如果不考慮服務端和客戶端所處的地域,僅僅簡單地進行負載均衡會對服務性能造成比較大的影響。

為了提昇在多地部署的情況下RPC請求的效率,我們設計了基於地域感知的就近路由功能,盡可能地將請求限制在同地區甚至是同可用區中。我們在SDK層面集成了接入了公司內部的CMDB,在應用啟動時,SDK會自動從CMDB獲取本實例的運行信息,包括可用區、地區等,並將這些進行作為註冊信息的一部分註冊至註冊中心,從而無需用戶關心應用部署的環境。

由於服務端和客戶端可能分屬於不同業務團隊,區域部署信息不對等的情況可能帶來流量負載不均、單區域熱點的問題。設想如下圖所示的場景,上下游系統地區部署不均勻,導致右邊地區的下游系統處理能力過剩,左邊則趨於飽和。

Apache Dubbo的愛奇藝之旅 6

當這種不均勻的情況更加嚴重時,時刻遵循區域親和性的調用原則會導致同區域的下游實例的處理水平無法匹配到上游的請求流量時,從而打垮下游服務,並且級聯影響到整個系統,此時的同區域路由效果甚至比跨區域的效果還要差,所以這就需要同區域路由有兼備服務端當前處理狀態的能力,做到適時的流量轉移。

為了避免這種情況的發生,我們額外引入了地區可用的策略。該策略也依託於上文提到的健康實例檢查策略,根據實例“健康”數是否達標來判斷該地區是否可用,如果某就近區域的健康實例數不足,負載均衡的範圍就將自動擴展至其他地域的實例。特別需要的指出的是,這裡對於健康的定義不只是實例宕機和不可達,也可以由用戶自行擴展,例如積壓請求數太多、處理速度過慢都可以認為其是不健康的。

加強服務安全

對安全性敏感的業務可能會有限制匿名調用的需求,如支付等。在加固安全性方面,我們引入了基於AK/SK機制的認證鑑權機制,主要架構如下圖所示:

Apache Dubbo的愛奇藝之旅 7

服務認證鑑權主要是為了解決兩個問題:消費端如何申明自己的身份以及服務端如何鑑別該身份是否有效。

Access Key Id /Secret Access Key的功能就是標識消費者的身份,並在調用時生成請求籤名以及由服務提供者對該簽名正確性驗證來識別某個請求來源的消費者身份是否有效,其間一切過程都對上層用戶透明。

並且,為了免去用戶在代碼中明碼配置敏感信息的操作以及為應用提供諸如AK/SK動態吊銷、更新的能力,我們引入了鑑權服務中心,其相當於一個身份和權限的註冊分發系統,使用鑑權服務的應用和鑑權服務中心的交互需通過HTTPS的雙向認證,並在TLS信道上進行數據交互,保證AK/SK信息傳輸的安全性。

具體的接入方式也並不復雜,以申請消費某敏感服務舉例:

  1. 使用者需要在微服務站點上填寫自己的應用信息,並為該應用生成唯一的證書憑證。
  2. 之後在管理站點上提交工單,申請某個敏感業務服務的使用權限,並由對應業務管理者進行審批,審批通過之後,會生成對應的AK/SK到鑑權服務中心。
  3. 導入該證書到對應的應用下,並且配置好證書的文件名等信息即可,代碼不需要做任何改動。

敏感服務自身在發布的時候,只需要導入本應用證書到classpath下,並在具體Service上配置好鑑權相關的參數即可,如下所示:

Apache Dubbo的愛奇藝之旅 8

該方案目前已經提交給Dubbo開源社區,並且完成了基本框架的合併。除了AK/SK的鑑權方式之外,通過SPI機制支持用戶可定制化的鑑權認證以及適配公司內部基礎設施的密鑰存儲。

後續展望

  1. Zookeeper服務受限於其CP模型和水平擴展性方面的缺陷,因此它可能並不是作為微服務註冊中心的最佳選擇,我們目前也在調研新的註冊中心服務,併計劃適時引入並提供平滑遷移的方案。另外我們也計劃依託於註冊中心的多地部署能力及SDK中的就近路由策略,形成系統性的多地部署高可用方案。
  2. 進一步加強管理平台的功能,完善服務治理的各項能力(如限流策略下發、壓測、遠程調試等等),配合內部微服務框架,打造集服務發布、測試、監控、調試的一站式服務治理平台。
  3. 探索Dubbo框架在雲原生環境及Service Mesh場景下的使用方式及相關過渡方案。

總結

短短6個月時間,愛奇藝已經上線幾千個Dubbo實例,並為Dubbo相關開源生態,包括Dubbo、Sentinel累計提交18個PR(其中已合併15個),並孵化一位DubboCommitter。得益於Dubbo在國內廣泛的應用和開源社區的積累,目前公司內部所有Dubbo應用平穩運行,沒有業務反饋過任何重大故障。在這之後會繼續完善Dubbo的服務治理功能和加強Dubbo的推廣,並緊跟Dubbo開源社區的腳步,將愛奇藝在Dubbo上積累的實踐經驗反哺給開源社區,共建Dubbo開源。

本文轉載自公眾號愛奇藝技術產品團隊(ID:iQIYI-TP)。

原文鏈接

https://mp.weixin.qq.com/s/QAAAXClyKKM9kAacdELu5A