阿里技術專家詳解Dubbo實踐,演進及未來規劃

技術瑣話發表於2019-01-17

阿里技術專家詳解Dubbo實踐,演進及未來規劃

本文首發於高效開發運維,技術鎖話授權轉載。

Dubbo 整體介紹,實踐案例,演進和未來發展

Dubbo 整體介紹

Dubbo 是一款高效能,輕量級的 Java RPC 框架。雖然它是以 Java 語言來出名的,但是現在我們生態裡面已經有 Go、Python、PHP、Node.JS 等等語言。在 GitHub 上,https://github.com/dubbo 下面已經有很多生態相關的東西。

阿里技術專家詳解Dubbo實踐,演進及未來規劃

Dubbo 是一個 RPC 框架,它和所有的 RPC 一樣,有一個最小執行子集,它需要 Provider、Consumer,以及一個服務註冊發現相關的東西,在 Spring Cloud 裡面是叫服務註冊發現,在 Dubbo 裡面我們叫它註冊中心(後面講到東西我們都以註冊中心來進行說明)。

簡單介紹一下 Dubbo 的整個啟動過程:

  • Provider 匯出一個服務,這個服務就是可被呼叫的;

  • 第二步,往註冊中心註冊這個服務;

  • Consumer 這端會來訂閱相關的服務,如果註冊中心裡面,Provider 列表有變化的話,它也會得到通知;

  • Consumer 會根據一定的路由規則從註冊中心拿到 Provider 列表,再根據一定的負載均衡策略,精確地呼叫到某臺 Provider 上去。

這就是一個簡單的一個 RPC 的調優過程。

Dubbo 在 2011 年就在 GitHub 上進行了開源,經歷了很多年的發展,整個社群一直非常活躍,現在 GitHub 上 Star 數已經高達 23K+,Fork 數 16K+。

在 2018 年 2 月份的時候,阿里巴巴已經把 Dubbo 的專案捐獻給了 Apache 社群,希望更多人能夠參與到 Dubbo 開發中來,希望依靠集體的智慧讓 Dubbo 變得越來越好。現在 Dubbo 的 committer,外部開發者的人數已經多於阿里巴巴開發者,包括微店,網易雲音樂,考拉,韓都衣舍等等。

Dubbo 因為開源這麼多年,積累了較多的使用者,包括很多網際網路的企業,包括阿里巴巴,考拉,滴滴等網際網路企業;還有很多中字頭企業,中國電信,中國人壽,中國工商銀行;還有一些比較傳統的企業。

Dubbo 的實踐和演進

Dubbo 服務註冊
 背景知識介紹
阿里技術專家詳解Dubbo實踐,演進及未來規劃

註冊中心註冊介紹

在 RPC 整個鏈路中,需要的元素有 Provider、Consumer,以及註冊中心(中間 Zookeeper 是作為註冊中心來使用的)。整個註冊過程如下:

  • Provider 會把一長串 URL(dubbo://xxx 的字串)寫入到 Zookeeper 裡面某個節點裡面去。

  • Consumer 的註冊也是類似,會寫到 Zookeeper 裡面某個節點(Consumer 寫入的原因,是因為 OPS 服務治理的時候需要實時的消費者資料)。

  • Consumer 發起一個訂閱,訂閱相關的服務。

  • 當某個服務的 Provider 列表有變化的時候,Zookeeper 會將對應的變化通知到訂閱過這個服務的 Consumer 列表。

從圖中我們可以看到 Provider 端的 URL 非常長,特別是當一個服務有大量方法的時候。Provider 端的 URL 會先從 Provider 到 Zookeeper,再往 Consumer 傳遞,這樣導致了單次傳輸的網路開銷比較大。

那麼再來看一下叢集的情形,圖中左邊有 N 個 Provider,右邊有 M 個 Consumer,那麼 Provider 釋出的時候,會遇到什麼情形呢?Provider 每次釋出它會先下線再上線,所以每個 Provider 釋出的時候,Provider 會傳送兩次通知,也就是傳送 2N 次;接收資料方有 M 個 Consumer,最後算出在整個網路裡面的推送資料的次數是 2N×M。

案例

來看一個真實的案例,在杭州有一家中等規模的電商公司,公司內部有 4000+ 個服務,以 Zookeeper 作為註冊中心,Zookeeper 有 100w 個節點,在釋出日的時候,公司內部網路的網路卡被打爆了,進而導致服務變更的推送失敗,新的服務註冊也失敗。整個叢集基本上處於不可用狀態。同樣的也收到了一些中小公司的反饋,每次在釋出的時候,網路也會有個抖動。

分析一下為什麼會出現這種情形。

Zookeeper 的 100 萬節點中,大約有 10 萬個 Provider 節點和 50 萬個 Consumer 節點。按照前面的演算法,在所有 Provider 同時釋出的極端情況下,有 2×10 萬×50 萬次推送,也就是說會產生 1000 億條的資料推送。針對每次推送的資料進行了一個統計,每條 URL 大小大概有 1KB,那麼計算出來的極端的推送資料量是 1KB 再乘以 1000 億,已經是 100TB 的級別了。

上面說的是極端情形,就算是釋出日也不可能同時進行釋出:有的應用釋出日不發版本,不同應用不可能同時釋出,同一個應用也需要分批發布。假設同一時刻釋出的量在千分之一,那麼推送的資料量也在 100GB,所以出現釋出日的時候間斷性地網路卡爆掉的現象就不足為奇了。每次釋出的時候,都會想著要跟別的應用釋出時間錯開,爭取單獨釋出,作為程式設計師還要糾結這個事情真是一個悲劇。

案例分析

來分析下現在的問題和需求:

首先,根據上述案例中的資料分析得知,效能出現了問題。推送的資料量非常大,儲存的資料量大,網路傳輸量大,服務推送延遲,網路卡堵塞,服務註冊不可用。

接著對 Provider 端那個很長的 URL 進行分析之後發現,不需要把整個 URL 寫到註冊中心裡,只需要把 IP 的埠寫進去就可以了,因為只有 IP 的埠需要實時變化。把其他資訊放到一個類似的 KEY-VALUE 結構的持久化儲存裡去,而且這個 KEY-VALUE 結構只要是應用級別就行了,節省了大量的儲存空間。

社群中對服務測試的需求非常強烈。要支援服務測試需求,就需要知道呼叫的服務方法名,入參出參的詳細資訊。所以這部分資訊也是需要儲存下來的。但是這部分資訊非常大,每個服務中可能有 10 多個方法,每個方法可能有三四個方法入參,入參和出參的完整資料結構往往非常複雜。這部分資料資訊也叫做服務的後設資料資訊。

首先來看一下怎麼解決效能的問題。主要有兩種方式可以解決:

  1. 怎麼減少當次的註冊量,就像前面分析的,只儲存 IP 的埠到註冊中心;

  2. 是否可以減少推送的次數,現在推送次數太大了。

 減少單次推送量

阿里技術專家詳解Dubbo實踐,演進及未來規劃

檢視上圖可知,Provider 端 URL 還是很長,期望簡化往註冊中心註冊的資訊;同時服務測試需求,又同時期望能將更豐富的後設資料資訊進行持久化的儲存。

Provider 端寫入的改造。Provider 往註冊中心寫的時候,將整個資料的寫入分成兩部分:

  • 寫入註冊中心;

  • 寫入後設資料中心。

註冊中心作為服務的註冊和發現,更加關注資料的實時性和有效性 (watch 機制),整個 URL 中 IP 和埠就能判斷某個服務是否可用,其他資訊都是相對固定不變的。所以註冊中心中,只需要儲存 IP 和埠。後設資料中心中儲存 URL 中除 IP 和埠外的其他資訊,加上服務測試需要的服務方法名,服務方法的出入參資訊。後設資料是一個 KEY-VALUES 的持久化儲存,是獨立於註冊中心的儲存,它不需要有 watch 的機制,而只需要提供持久化儲存。圖中使用的的 KEY VALUE 儲存是 Redis,但是後設資料中心定義了一套 SPI,開發者可以去擴充套件,可以自己實現 DB 儲存,或者其他持久化儲存的方式。

Consumer 端獲取 Provider 列表資訊的改造。Dubbo 之前的版本中,直接從註冊中心裡面獲取 Provider 端的服務資訊,獲取到的資訊已經是一個完整的可呼叫的服務資訊。但是 Provider 端寫入改造之後,原有 Consumer 端獲取的 Provider 服務資訊的方式不可用了。除了從註冊中心獲取到的資料之外,還需要從後設資料中心裡拿到後設資料資訊,然後對這兩部分資料做一個 Merge 之後才能構建出完整的可呼叫的服務資訊。

當前 Dubbo2.7 版本還沒有完全去除所有引數,而是採用先去除部分引數的方式來驗證;後續會逐漸迭代完善,同時在 2.6.x 版本中也會進行一些相容方案的支援。

 應用級服務註冊

上面的改造針對的是怎麼減少單次的推送資料量,針對的還是服務維度。期望中最理想地給註冊中心減負的方式是應用維度的服務註冊和發現,可以參考 Spring Cloud 體系下的 Eureka 實現。一旦實現這種方案,服務註冊中心就再也不會成為 RPC 領域的瓶頸,而且可以認為這種方案是服務註冊的 終極方案

當然這種實現方式做的改動相對比較大,不僅需要將服務執行和運維完全分開,而且需要一定的架構體系改造來支撐具體服務的發現。到目前為止還沒有形成成熟可靠的方案,團隊內部也只是在探討階段。

 服務變更推送開關

所謂服務變更推送開關,就是針對任何的服務資訊的變更,不進行推送。

到底哪種情形需要這種開關呢?阿里巴巴整個叢集的機器數非常大,所以宿主掛掉或者虛擬機器掛掉出現的概率比較高。在每年雙十一的時候,大部分消費者都會去淘寶天貓上購物。在 11 月 10 號 11 點 50 幾分開始,大量買家在拼命地重新整理購物車或者商品詳情頁面,這時候阿里巴巴內部的系統負載是非常高的,網路負載也非常高。如果這時候,有一臺機器因為宿主機掛了的原因而導致部分服務下線,這時候需要推送相關應用服務下線的變更給對應的服務 Consumer。這時候就需要佔用網路頻寬,可能對服務呼叫產生影響,進而還會對雙十一造成很大的壓力。所以這時候就希望有一個開關,能夠把整個服務推送關掉。

但是這時候也會帶來一些問題,當服務 Provider 不可用的時候,註冊中心沒有向服務 Consumer 推送變更通知,服務 Consumer 請求的時候可能會報錯,這時候的小部分服務出錯可以允許的;保證整個叢集上萬臺機器,特別是整個雙十一核心鏈路的穩定性才是雙十一最重要的使命。

 服務分組

在一個大的叢集環境中,在沒有路由規則的情況下,Consumer 叢集會呼叫整個 Provider 叢集中的任何機器。服務分組,就是對 Consumer 叢集和 Provovider 叢集進行分組,將大的服務級分成幾個子集。

舉個例子,叢集中有 8 個 Consumer 例項,有 8 個 Provider 例項,按照正常流程 Consumer 這 8 個例項會呼叫 Provider 任何一臺,任何一個 Provider 的變更通知也會通知到這 8 個 Consumer 例項。但是如果對它進行分組呢,Consumer 例項叢集分成 A 和 B 兩個組,Provider 叢集也分成 A 和 B 兩個組。Consumer 中 A 的組只能調到 Provider 中 A 組的服務;Provider 的 A 組中的例項在釋出過程中,也只會推送到 Consumer 的 A 組中,而不會推動 Consumer 的 B 組。最終通過推送的範圍,來減少了推送的資料總量。

對於服務分組的的實現,這裡不做展開,本文後面再次講到服務分組的時候,會稍微展開陳述。

 服務註冊中心

前面陳述的服務註冊相關的改造和方案,都是圍繞 Dubbo 等 RPC 進行的。接著來看一下在網際網路環境下,理想的註冊中心是什麼樣子的。(以下闡述只代表個人觀點)

CAP 理論:現在大部分主流而且在使用中的註冊中心都是滿足 CP 的,但是在網際網路大叢集環境下,期望的結果是滿足 AP 的同時,能夠滿足最終一致性。在大叢集環境下,可用性往往比強一致性的優先順序更高。以 Zookeeper 為例,Zookeeper 能夠為分散式系統提供協調功能的服務,預設提供強一致性的資料服務,但是它在某些情況下是允許 Zookeeper 是不可用的。列舉一個場景,Zookeeper Leader 失效了,這時需要重新選舉 Leader,而這個選舉過程需要 30 秒以上 (資料來自於網上的文章),這段時間內 Zookeeper 對外是不可用的。

去中心化:Zookeeper 是有 Leader 機制,往 Zookeeper 裡寫資料都是往 Leader 裡面寫,這個 Leader 其實就是一個單點。所以整個寫的過程是中心化的。而且 Zookeeper 對跨城跨機房的方案上,支援非常有限。

資料推送的強控制:期望對推送的有更加強的靈活性。還是以 Zookeeper 為例,Zookeeper 中有 watch 機制,每個資料節點發生變更的時候,就會往外推送變更的通知。但是作為註冊中心,我們期望能夠控制它的推送頻率,針對新增節點只需要一分鐘裡面推送 6 次就可以了,每十秒推送一次,這樣可以合併一些變更通知,減少網路資料請求的資料量。

容量:Dubbo 是單程式多服務的方式來註冊服務的。這也就意味著註冊中心中需要儲存的資料量較大,所以要有足夠的容量來支撐這種場景。

那些註冊中心產品:Zookeeper 作為服務註冊中心的公司在減少,那麼現在有哪些方案,可以來替代呢?

  • Eureka 是一個 AP 的應用,而且它是去中心化的。但是它有幾點不足:

在我們的內部的效能測試中,它效能表現非常一般,效能大概只有 Zookeeper 的 60% 左右。

Eureka 內有一種契約機制,它每隔 30 秒會發起一個續約的請求,如果 3 次沒有接收到,它才會過期失效;如果一個服務非正常退出(沒有發起解約請求),那麼就存在這個超時的間隙期,服務是不可用的。所以在生產環境,對服務敏感的相關應用方是無法滿足需求的。

Eureka 是應用維度的服務註冊,當前的 dubbo 是服務維度的註冊,如果要匹配的話,需要大範圍改造。

Netflix 宣佈了停止更新 Eureka 2.0。

  • Etcd 是 Zookeeper 的升級版,它參考了 Zookeeper 的很多實現,同時進行了較多優化。Etcd 的強一致性協議和程式碼實現更加簡單,它的部署方式也更加簡單,它支援了 Rest 的方式進行相關訪問,它的效能相對 Zookeeper 來說也有了一定的提升。但是它還是一個 CP 的系統,它也是要求資料的強一致性,而犧牲部分的可用性。

  • Consul 相對前面幾個產品來說,更加專注服務註冊發現本身,它是一個比較專業的服務註冊中心。Consul 有了後臺管理頁面,它有了健康檢查,Consul 原生支援多資料中心。但它的效能上有瓶頸的,它和 Zookeeper 和 ETCD 進行對比,它效能是稍微差一點的;同時 Consul 也要求資料的強一致性而犧牲部分可用性。

  • Nacos 是阿里巴巴開源的一個產品,內部系統也在使用,它已經經受了一定流量和使用者的考驗。現在阿里巴巴集團內部的 Provider 和 Consumer 數量已經到達了億的級別,它現在能夠支撐上億級別的訂閱量,整體經受了一定的實踐檢驗。Nacos 整體設計是去中心化的,而且設計上滿足 AP 和最終一致性,效能上和 Zookeeper 比較接近。

前段時間和網易考拉在溝通過程中也發現,他們也在做一個自己的註冊中心;新浪也有一個自己的服務註冊中心。所以許多大的網際網路公司,因為定製或者差異化的需求,都在自研註冊中心。

配置中心
當前困境
 應用開發者

Dubbo 內部有一個配置檔案叫 dubbo.properties,這種配置方式和 Spring Boot 的 application.properties 是比較像的。每次新開發一個 Dubbo 應用的時候,應用開發者都需要去寫一大堆的配置到 dubbo.properties 中,包括註冊中心的地址,後設資料中心的地址,應用級別的超時時間等等。當所在公司只有兩三個應用的時候,一個個應用單獨設定的方式是沒問題的;當業務快速發展的時候,應用數從 2 個變成 20 個應用的時候,那麼所在的技術團隊可能需要整理一份快速構建應用的文件,供應用開發者參考使用,而且這個文件需要及時維護更新。如果這時候還需要更改註冊中心地址(原來 2 個應用的時候,Zookeeper 的地址用 IP 來快速實現,現在想換成域名了),意味著要去推動這 20 個應用的開發者,讓他們修改對應的配置,然後測試並且釋出。整個過程非常痛苦!需要有一種類似於 Spring Cloud Config 的配置方式來滿足集中式的配置方式,相當於一個遠端集中式的 dubbo.properties。

 Dubbo 開發者

Dubbo 2.7 以前的版本中,服務路由規則,服務治理規則的資料都是儲存在註冊中心中的。之前大部分使用者都選用 Zookeeper 作為註冊中心,Zookeeper 兼具了 Key-Value 的功能,所以之前的版本中執行起來是沒有問題的。 但是如果選用的註冊中心,不具有持久化的功能,這時候的路由規則和服務治理規則就沒地方儲存了,整個系統就玩不轉了。作為 Dubbo 開發者,期望將服務治理和服務路由規則分開儲存到一個集中式的 Key-Value 儲存中。

要解決上述兩個痛點,需要在 Dubbo 中引入一個遠端的集中式的配置中心,這個配置中心儲存了遠端的 dubbo.properties,路由規則,服務這裡規則等。

 應用架構師

舉個場景,一個公司的所有應用已經引入了 ETCD 作為自己的應用的動態配置管理,但是在引入 Dubbo 以後,Dubbo 中又有幾套對應的動態配置可供選擇,如 Nacos、阿波羅,Zookeeper。這就要求公司層面需要維護兩套動態配置的 Server,這個成本比較高,而且增加了系統的穩定性的風險。對於架構師來說,需要 Dubbo 能支援 ETCD 的動態配置。

解決方案

阿里技術專家詳解Dubbo實踐,演進及未來規劃

圖中分成上下兩部分,下面黃色部分就是它的一個儲存;上面的整個部分是 Dubbo 內部實現。上文中所講的動態配置,在 Dubbo 中定義為配置中心。

在實現層面,在 Dubbo 中定義了一層 SPI,預設實現的 Zookeeper,Apollo,Nacos。應用架構師去擴充套件這個 SPI 就可以完成 ETCD 的定製,這樣就能達到和原有的應用中使用 ETCD 方式相容。

對於運維工程師來說,原來的一個註冊中心的地址變更要推動每個應用開發者去做變動,應用開發者非常煩,運維工程師很吃力。現在只需要在遠端的 dubbo.properties 裡進行統一去升級,然後通知相關的應用開發者進行一些適當的驗證。

因為已經定義了配置中心的 API,Dubbo 開發者直接呼叫對應的 API 來實現服務規則和路由規則的儲存。

三個中心

三個中心就是前面講到的註冊中心,配置中心,後設資料中心。

阿里技術專家詳解Dubbo實踐,演進及未來規劃

期望的使用方式:Provider 先去配置中心裡獲取註冊中心的地址和後設資料中心地址,再根據拿到的註冊中心地址去對應的註冊中心註冊服務,根據拿到的後設資料中心地址寫入後設資料資訊到對應的後設資料中心 Server。Consumer 和 OPS 也是類似的。

通過配置中心這種集中式的配置方式,可以讓開發者從原來煩瑣的配置中解脫出來,讓它更聚焦於業務的開發,而不需要關注框架層面的東西。

路由規則
路由規則組合

阿里技術專家詳解Dubbo實踐,演進及未來規劃

Dubbo 路由規則,按照覆蓋範圍可分為應用級別,服務級別,方法級別路由規則;按照功能緯度,可以分為黑名單,條件路由 ,TAG 路由規則。大部分路由需求都是可以通過組合來實現的,如應用級的黑名單可以通過應用級別 + 黑名單路由規則方式組合。

全鏈路灰度釋出

某產品新開發了一個新特性,想進行 A/B Test,讓部分使用者開放新功能體驗;或者產品在迭代過程中,想進行下改造功能的灰度驗證。在當前微服務的架構體系下,一個新功能往往依賴整個呼叫鏈路的上下游一起完成。所以這兩種新功能的驗證,基本不可能在單機上完成,往往需要服務鏈路的上下游一起隔離出一部分機器進行驗證。在這裡,稱為全鏈路灰度釋出驗證。

阿里技術專家詳解Dubbo實踐,演進及未來規劃

全鏈路灰度釋出草圖

來看一種最簡單的場景。客戶在瀏覽器端發起一個 HTTP 請求,這個請求會根據一個負載均衡策略訪問到一臺 web 伺服器 (30.5.127.44),這臺機器會呼叫服務 A 叢集,服務 A 叢集會呼叫服務 B 叢集。業務開發者開發了一個新功能,想線上上驗證功能的正確性,但是又不想原有的功能受影響。也就是說想從服務叢集裡拿出少部分例項去驗證線上的功能。假設下需求,希望總使用者的千分之五的使用者能夠走到新功能的流程,幫助驗證新功能的正確性。

  • 從服務 A 叢集中選出一臺機器(30.5.120.16)作為灰度驗證的機器,從服務 B 叢集中選出一臺機器(30.5.128.66)作為灰度機器。對選出的這兩臺機器 打上標canary(金絲雀)。

  • 需要在 Web 伺服器執行的程式碼邏輯中,增加邏輯:獲取到使用者的 UserId,UserId 對 1000 求模之後小於 5 的,在 Dubbo 對服務 A 叢集發起請求之前帶上 Tag=canary(在 Dubbo 中是通過設定 Attachment 來完成)。

  • Dubbo 自帶的 Tag 路由規則會做以下事情:Dubbo 會先拿到要呼叫服務所在的應用名;再根據應用名 +Tag 路由規則的名稱 canary, 去獲取到對應的機器列表,Web 服務就拿到了 30.5.120.16 這臺機器;Dubbo 根據拿到的機器列表依據負載均衡策略發起請求。相應的 Web 伺服器中沒有打上標的機器,會訪問到其他機器 (30.5.120.26),而不會訪問到已經被打上標的機器。Tag 路由規則,完成了對相應 Provider 和相應 Consumer 端的隔離。

  • 通過 Tag 路由規則已經解決了 Web 叢集到服務 A 叢集這裡面的鏈路,但是怎麼解決服務 A 叢集到服務 B 叢集的 Tag 的傳遞呢?現在比較流行的一些全鏈路跟蹤的產品可以幫我們做到,如 Open Tracing,Zipkin。我們以 Zipkin 為例,通過 Zipkin 實現 Dubbo 的 Filter 可以把這個標從 Web 叢集傳到服務 A 叢集再傳到服務 B 叢集,整個鏈路都可以傳遞下去。

  • 整體呼叫鏈路總結。滿足灰度驗證的使用者鏈路:web 服務 -> 30.5.120.16 -> 30.5.128.66; 不滿足灰度驗證的使用者 (不打標) 鏈路:web 服務 -> 叢集中 30.5.120.16 之外的機器 -> 叢集中 30.5.128.66 之外的機器。

通過上述步驟已經完成了全鏈路的灰度環境搭建,這種方式的應用範圍非常廣,可以按照自己的業務場景和需求進行一些調整來達到自己期望的效果。下面叢集中也有案例進行說明。

叢集

從叢集角度來看下,服務例項之間的隔離。假設一個 Provider 叢集有 8 個例項,Consumer-A 叢集有 4 個例項,Consumer-B 叢集有 4 個例項; Consumer-A 叢集和 Consumer-B 都會呼叫 Provider 叢集。

阿里技術專家詳解Dubbo實踐,演進及未來規劃

服務分組:以 Provider 和 Consumer-A 為例。將 Provider 分成左 (1、2、3、4) 和右 (5、6、7、8) 兩個組,將 Consumer-A 分成左 (1、2) 和右 (3、4) 兩個組。Consumer-A 中左組只能呼叫到 Provider 中的左組,Consumer-A 中右組只能呼叫到 Provider 中的右組,而不會呼叫到整個叢集的其他例項。服務分組除了能讓註冊中心減少推送的資料量外,還能減少 Consumer 和 Provider 長連線的數量,從而帶來一定的效能提升。

服務分組最簡單的實現方式,在 Dubbo 的 Service 和 reference 中配置中配置多個 group,進行手動匹配。

更高階的服務分組實現方式,通過路由規則的方式進行動態匹配,路由規則中根據一定的規則(如根據 Ip 的最後位的奇偶數)將 Provider 和 Consumer 進行分組,然後路由規則裡去完成隔離。這種方式暫時還沒有發現較好的實現。

業務隔離:來看個現實的場景,阿里巴巴交易平臺承接的業務非常多,在新零售出來之前,所有的業務都是線上交易,在出現 2 分鐘的不可下單的時候,體驗糟糕但是還不會引起大範圍的騷亂。但是在盒馬鮮生線下購物的時候,如果出現 2 分鐘不能下單,那在排隊的消費者意味著要乾等兩分鐘,這是非常糟糕的體驗。

抽象下上面的場景,用更加產品化和技術化的方式來分析。以 Provider 和 Consumer-A,Consumer-B 為例。Provider 叢集的消費者非常多,包括 Consumer-A,Consumer-B 或其他 Consumer 叢集。因為 Consumer-B 的業務非常重要,不想讓其他機器的故障,影響到 Consumer-B 的穩定性,所以 Provider 中來自於 Consumer-B 的流量需要進行隔離。業務隔離的實現方式,可以採用 Tag 路由規則的方式來實現。對 Provider 叢集的 7,8 機器打上標 -BTag(即路由規則,可以通過 OPS 打標),然後在 Consumer-B 叢集中呼叫 Provider 之前 setTag=BTag (在 Dubbo 中在 attachment 裡設定 tag 值)。

灰度環境

  1. 單機灰度的話,只要在釋出的時候,可以單臺機器釋出就可以。

  2. 全鏈路灰度,需要在整個叢集中圈出一批機器,如從 Provider,Consumer-A,Consumer-B 叢集中選出 3 號機器作為灰度環境。全鏈路灰度的實現已經在前面說明,用 Tag 路由實現。

服務測試
Dubbo 服務測試

阿里技術專家詳解Dubbo實踐,演進及未來規劃

Dubbo 在啟動時,會匯出服務,讓服務是可被呼叫的;同時它還會向後設資料中心寫入後設資料資訊(包括服務方法的方法名,路參,出參等資訊)。

服務測試是在 Dubbo OPS 後臺中的功能。服務測試業務流程:先去後設資料中心獲取後設資料資訊;在頁面中展示服務的結構體,等待使用者輸入;使用者輸入引數資訊;Dubbo OPS 後臺根據後設資料資訊和使用者輸入的引數構造出服務呼叫的入參,向相應的 Provider 發起泛化呼叫。泛化呼叫被較多的閘道器係統使用。

Swagger 整合

除了服務測試功能外,還需要:

  • 文件功能。自動生成文件,生成的文件是視覺化的,而不是 JSON 等檔案格式。

  • 自動化測試。

Swagger 可以滿足以上需求。但是 Swagger 和 SpringMVC 結合緊密,SpringMVC Rest 介面加上註解之後,可以快速整合 Swagger。

阿里技術專家詳解Dubbo實踐,演進及未來規劃

要讓 Dubbo 能夠通過 Swagger 方式生成文件和進行自動化測試,需要做兩個事情:

  1. 將 Dubbo 介面形式轉換成 Swagger 文件。Swagger 是有文件規範的,只要將介面形式轉換成 Swagger 約定的格式,就可以滿足 Swagger 文件的形式進行輸出。

  2. Swagger 服務測試功能。外部 HTTP 請求到一個 Controller,Controller 需要將 HTTP 請求轉換成 Dubbo 請求,包括引數的對映和服務的對映。

服務治理
Hystrix 停更

Hystrix 停更了,在 GitHub 官網上推薦了 Resillence4j,阿里巴巴也開源了 Sentinel。這裡進行一個簡單的比較。

阿里技術專家詳解Dubbo實踐,演進及未來規劃

Hystrix 的兩塊功能,隔離和熔斷,能滿足大部分需求但是停止更新了。

Resillence4j 要求 JDK8 及以上,對 function 程式設計更加友好。

Sentinel 在阿里內部使用的範圍非常廣,已經經受住了一定的考驗。每年雙十一在買東西的時候,如果出現一個頁面上顯示系統繁忙請稍候重試,或者顯示人太多了請排隊,這時候其實就是 Sentinel 在後臺發揮作用了。Sentinel OPS 這塊做得非常好,達到了開箱即用的標準。

服務治理清單
 不要設定應用級別重試

在 Consumer 端設定重試,必須保證 Provider 端多次呼叫是冪等的。

設定應用級別的重試,會讓已經壓力倍增的系統雪上加霜。舉個例子,Provider 系統的執行緒數是 200,當 Provider 某個服務出現問題,導致 RT 從 200ms 變為了 3500ms;Consumer 因為設定了預設重試且重試次數為 3,這就會導致 Provider 執行緒池很快會被耗盡。

所以,預設不要設定應用級別的重試,對有業務需求的服務單獨設定重試的規則,並且保證 Provider 端服務的冪等性。

 設定超時時間

設定超時時間,能夠防止系統雪崩和資源耗盡。一個 Consumer 呼叫 Provider 的時候,Provider 需要 3 秒處理完業務邏輯之後返回結果,Consumer 預設是同步呼叫,需要某個執行緒同步阻塞等待 3 秒,也就是說如果沒有超時機制,很容易將 Provider 的問題傳遞給 Consumer 並且不斷往上傳遞。如果 Consumer 設定了超時時間 200ms,Provider 加入需要 3 秒處理完結果,但是不會將問題傳遞給 Consumer。

建議的超時時間是一百毫秒到兩百毫秒左右,對於特殊業務進行特殊設定。

 隔離

隔離包括例項隔離和執行緒隔離。例項隔離,就是前面講到的服務分組和業務分組,通過例項隔離達到問題和影響面的隔離。

執行緒隔離,可以分為靜態隔離和動態隔離。靜態隔離,首先通過一定的分析方法找出一些比較慢的方法,或者甄選出業務上比較重要的服務方法;再對這些服務或者方法單獨設定執行緒池以及對應的執行緒個數。動態隔離是在 Dubbo 應用執行態的時候,自發地調整執行緒池的隔離。Dubbo 應用裡預設的執行緒數是 200 個,200 個消耗完之後,新的請求進來就會返回執行緒池滿的異常。這時候 Dubbo 內部會對執行中的服務方法進行統計,統計出併發執行緒數>8,RT>300ms(假設的一個指標) 的服務,把這些服務扔到獨立的執行緒池裡去完成,後續這些服務的執行都會由這些新建的執行緒池的執行緒執行,其他服務仍然在這 200 個執行緒池裡面執行。當這些隔離的服務方法執行一段時間後,它的 RT 變得正常了,那這部分獨立出去的執行緒池可以被銷燬,這些服務方法可以重新由原來的 200 個執行緒執行。整個過程的調整是動態的。整個動態隔離的機制和 Hystrix 的執行緒隔離有些相同的含義。

 治理工具

每個微服務實踐的時候都會講到。微服務最佳實踐裡面,強鏈路跟蹤,限流,降級、熔斷等,都可以在系統裡引入,進而保證系統的穩定性。

 系統可驗證

系統可驗證主要包含兩方面,第一個是環境是可被驗證的;第二個是通過一定的測試手段和方法來保證系統是可測試和可驗證的。

環境可被驗證,有些場景需要支援單機的灰度,有些場景需要全鏈路的灰度。

測試方面:在系統上構建介面級別的服務測試,自動化測試,支援全鏈路壓測。通過服務測試和自動化地執行來增強系統的正確性測試;通過全鏈路壓測,來判斷全鏈路的瓶頸在哪裡。

Service Mesh

Service Mesh 在 2018 持續火熱,阿里巴巴和螞蟻都在這一塊有佈局。現在阿里內部主要在兩個場景中去做嘗試,第一個是跨語言。阿里大部分語言是 Java,但是有少部分是 C++,還有部分 NodeJS,需要 Service Mesh 去解決跨語言之間的呼叫。第二個是異構系統。阿里巴巴收購了一些公司,但收購進來公司的技術棧和集團內部不一致,它可能是 Java 語言,但是使用的 Spring Cloud 的微服務體系,還有一些公司沒有使用 Java 語言,需要通過 Service Mesh 來解決這種異構系統之間的呼叫問題。

阿里技術專家詳解Dubbo實踐,演進及未來規劃

從實現方式上來說,阿里沒有重複的造輪子,控制層這一塊(也被稱為 sidecar),是在 Envoy 上進行了一些擴充套件,實現了一個 Dubbo Filter,現在這部分程式碼已經被捐獻到了 Envoy 的社群。資料層實現方式是對 Istio 做了一些擴充套件和定製。因為 Istio 有一套預設的服務發現,服務治理的產品,但阿里巴巴有自己的服務發現,動態配置管理,服務治理的產品方案。在資料層,會將 Istio 和阿里巴巴中介軟體的產品做一些整合,來滿足需求。

從部署結構上看,Dubbo 應用和對應的 Envoy 實現是部署在一臺機器上 (虛擬機器) 的,只是以兩個程式的形式存在。Dubbo 應用需要呼叫 Spring MVC 應用中的服務,每一次發起呼叫的時候,Dubbo 應用會首先呼叫到同一臺機器上的 Envoy 程式,再呼叫到另外一臺機器上的 Envoy 程式,另外一臺機器的 Envoy 程式再呼叫 SpringMVC 應用。整個呼叫過程多了兩跳。

阿里巴巴已經在鹹魚的一些場景上在做 Service Mesh 的驗證,同時程式和架構也在持續優化過程中。

Dubbo 現狀和未來
當前工作
 核心特性

針對 2.7 之前存在的若干非同步問題進行了優化。在 Dubbo2.7 之後,開始全力擁抱 JDK8。所以 2.7 版本將基於 JDK8 中的 CompletableFuture 做出一些針對性的增強來支援非同步,類似於 Promise 方式。

優化服務治理引數配置,升級服務路由規則,同時對應的 OPS 也進行了相應的升級。Dubbo2.7 之前的路由規則對應關係一個服務可以對應多條規則,優化之後一個服務只能對應到一條規則;新增了前文講到的 Tag 路由;服務治理引數,路由規則的資料儲存都將使用配置中心。

社群裡面分支演進分成 2.6 版本和 2.7 版本。2.7 版本主要有一些新功能的迭代,2.6 以維護為主。如果 2.7 裡有些功能可以被 2.6 借鑑的話,也會往 2.6 裡面疊加。

 Spring Boot

新增了一個工具頁面,用於快速構建 Dubbo 的 Spring Boot 的應用。這個參考了 Spring Boot 的模式。

在 Dubbo 體系下,有一個 Dubbo Spring Boot 工程來支援 Dubbo+Spring Boot 的整合。到目前為止支援 Dubbo2.6.X 版本,支援 Spring Boot 1.5.x 和 2.0.x。因為 Spring Boot 的 1.5 和 2.0 的分支差距比較大,所以 Dubbo Spring Boot 也維護了兩個版本。後續 Spring Boot 1.X 會在 2019 年停止更新。

 Dubbo OPS

Dubbo OPS 進行了全新的升級,有了一個新的 UI,合併了 Dubbo Admin 和 Dubbo monitor 兩個應用,而且整個 OPS 用了 Spring Boot 工程結構,從而真正達到了開箱即用。Dubbo OPS 能夠同時支援 2.6 和 2.7 的版本的執行,對新功能進行了相應的配置支援。

 開源建設

Dubbo 捐獻給了社群之後,重新搭建了新的官網,新的中英文文件,有了中英文部落格,整個社群現在非常活躍。在這半年多依賴,和一些深度使用 Dubbo 的客戶做了一些交流,如工商銀行,考拉等等。今年舉辦了 5 場 Meetup,包括杭州,成都,深圳,北京,上海,吸引了大量的開發者參與。

 生態建設

  1. 正如前面所說,在多語言方面,社群引入了 PHP,Go,NodeJS,Python 等。

  2. 對現有的一些生態元件進行持續升級和維護。

  3. 引入了一些新的擴充套件元件,包括 SkyWalking,ETCD 等等。

未來規劃
 社群投入

社群持續投入,包括 PR,Issue 跟進,優秀部落格和文件的持續輸出。當然整個運作形式是根據 Apache 的方式進行運作,而 Apache 溝通的最主要形式就是郵件,所以各開發者可以訂閱 Dubbo 的郵件列表進行持續跟蹤。

持續推進 Dubbo Meetup 和客戶交流。

 功能增強和 Issue 跟進

持續功能增強和優化,包括前面的註冊中心的優化,路由規則的持續增強和優化。現在 Dubbo 的 committer 中,阿里只佔了小部分,其中來自於網易音樂和考拉,微店,韓都衣舍,有贊等公司的開發者也非常活躍。最近有一位印度的開發者,也正式成為了 Dubbo 的 Committer。

 生態建設

因為現在生態中,部分實現已經有了重疊,包括後續進來到我們生態體系裡的擴充套件也會造成同樣的擴充套件或者實現出現重疊,這時候會進行一些優勝劣汰。

Dubbo 和 SpringCloud 關係,部分同學在選型的時候覺得要麼選 Dubbo,要麼選 SpringCloud,兩者互相排斥的。其實不是這樣的,這塊的詳細描述,可以關注公眾號:阿里巴巴中介軟體。裡面會有一些文章的描述和分析。

 Dubbo 3.0

Dubbo 3.0 的進展,比較受到關注。因為涉及到 Dubbo 和 HSF 整合,以及一些新特性的開放,如 reactive 的引入。但是整個過程是非常漫長的,因為兩個產品不可能完全融合,需要有一些特性存在。而且在完成之後,整個遷移的過程非常巨大。今年上半年,會有一個預覽版本,現在很大一部分人力已經投入到 Dubbo 3.0 的研發中。

 Service Mesh

Service Mesh,現在還在測試階段,整體還未達到生產環境的級別。還需要不斷優化效能和不斷在各個場景中試用。


嘉賓介紹

阿里技術專家詳解Dubbo實踐,演進及未來規劃

曹勝利,阿里巴巴中介軟體技術部技術專家。2010 年加入阿里 B2B 中國網站技術部,先後在 1688 技術部,菜鳥技術部負責業務產品;曾負責阿里採購平臺的架構和服務化改造工作;目前在阿里巴巴從事應用容器和微服務框架的開發、實施以及效率提升相關的工作。關注分散式架構、微服務,特別是 Spring,Spring boot 生態的發展。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31562044/viewspace-2564081/,如需轉載,請註明出處,否則將追究法律責任。

相關文章