平滑遷移 Dubbo 服務的思考

前言

近日,有報道稱在 HashCorp 的商業軟件試用協議上發現,旗下所有商業產品禁止在中國境內使用、部署、安裝,這其中就包含了 Terraform, Consul, Vagrant 等衆多知名軟件,其中 Consul 是一個在微服務領域的開源軟件,可以用於做註冊發現、配置管理等場景。

該新聞在國內發酵後,有人在 Twitter上諮詢了HashCorp 公司的創始人,得到的回覆是影響的軟件僅限於 Vault 這款加密軟件,目前 HashCorp 公司的官方網站上已經更新了相關的條款,明確了受影響的產品僅限 Vault 這一款產品。

Consul 開源版是否收到影響?

上面的條款裏只提到了商業軟件,那麼開源的 Consul 是否受到影響呢?在 Github 的 Consul 倉庫上,可以得知項目的 license 是 Mozilla Public License 2.0 ,這款許可證在 Apache 官網上是 Category B , 屬於 Weak Copy Left 許可,那麼它有哪些特點呢?

  1. 任何可以使用,複製,修改,重新分發該代碼,包括商業目的使用。

  2. 如果修改了 MPL 協議許可下的源碼,再重新發布這部分源碼的話,必須保留原來 MPL 許可證不得更換。

  3. 如果基於該項目衍生出更大的項目,那麼這部分工作可以使用新許可證的方式進行分發,只要沒有修改原來 MPL 許可下的代碼。(這也是爲什麼 Apache 項目的分發的源碼中可以包含 MPL 協議下二進制文件的原因)

可以看到,MPL 通常被認爲是介於 Apache License 和 GPL/LGPL 之間的一個折中方案。相對於 Apache License,MPL 2.0 要求修改了源碼必須保持相同協議;相對於 GPL/LGPL, MPL 2.0 可以商用,同時衍生的作品在一定條件下也可以更換許可證類型。

總體來看的話,開源版 Consul 無論是私用還是商用都是不受限制的。但這也可能是一個警鐘,如果對 Consul 還是有所顧忌的話,如何替代掉它呢?

在微服務領域,Consul 主要被用來做充當註冊中心和配置中心,例如 Dubbo 和 SpringCloud 都有對應的支持。本文便以這個事爲一個引子,介紹如何平滑地遷移 Dubbo 服務,達到替換註冊中心的效果。

平滑遷移服務的定義和意義

如果 Dubbo 應用已經部署到生產環境並處於正常運行狀態中,此時想將應用的註冊中心替換,那麼在遷移過程中,保證業務的平穩運行不中斷一定是第一要義。我們將保證應用運行不中斷,並最終達成註冊中心替換的過程稱爲平滑遷移。可以類比爲給飛行中的飛機替換引擎,在項目升級、框架調整等很多時候,現狀和終態之間往往都有一個過度方案。

  • 平滑遷移可以避免終態方案一次性上線後出現和原有方案的不兼容性,規避了整體迴歸的風險

  • 沒有哪個互聯網公司可以承擔的起:“自 xx 至 xx,系統維護一小時,期間服務將無法提供,請廣大用戶諒解” 這種停機升級方案。

平滑遷移過程

說到註冊中心遷移,可能很多人第一時間都能想到雙註冊雙訂閱這種方案

雙註冊和雙訂閱遷移方案是指在應用遷移時同時接入兩個註冊中心(原有註冊中心和新註冊中心)以保證已遷移的應用和未遷移的應用之間的相互調用。

以 Consul 遷移到 Nacos 爲例:

在遷移態下,一共有兩種應用類型:未遷移應用,遷移中應用。我們所說的雙註冊雙訂閱都是指的【遷移中應用】。明白下面幾個點,平滑遷移的過程一下子就清晰了:

  • 【未遷移應用】不做任何改動

  • 爲了讓【未遷移應用】調用到【遷移中應用】,要求【遷移中應用】不僅要將數據寫到 Nacos,還要寫回舊的 Consul,這是雙註冊

  • 爲了讓【遷移中應用】調用到【未遷移應用】,要求【遷移中應用】不僅要訂閱 Nacos 的數據,還要監聽舊的 Consul,這是雙訂閱

  • 當所有應用變成【遷移中應用】時,舊的 Consul 就可以光榮下崗了,至此平滑遷移完成。

在這個過程中,還可以靈活的變換一些規則,例如在遷移中後期,大部分應用在 Nacos 中已經有服務了,可以切換雙訂閱爲單訂閱,以驗證遷移情況。並且在真實場景下,還會並存配置中心、元數據中心的遷移,過程會更加複雜。

Dubbo 平滑遷移方案 – 多註冊中心

Dubbo 多註冊中心配置文檔地址:http://dubbo.apache.org/zh-cn/docs/user/demos/multi-registry.html

本文的完整代碼示例將會在文末提供,其中 Consul 註冊中心搭建在本地,而 Nacos 註冊中心使用的是阿里雲的雲產品:微服務引擎 MSE,其可以提供託管的 Nacos/Zookeeper/Eureka 等集羣。

Dubbo 支持多註冊中心的配置,這就爲我們平滑遷移提供了很多的便利性。在使用 dubbo-spring-boot-starter 時,只需要增加如下的配置,即可配置多註冊中心:

dubbo.registries.first.protocol=consul
dubbo.registries.first.address=localhost:8500

dubbo.registries.second.protocol=nacos
dubbo.registries.second.address=mse-kirito-p.nacos-ans.mse.aliyuncs.com:8848

在 Consul 控制檯可以看到服務已經註冊成功:

在 MSE 控制檯可以看到 Nacos 服務也已經註冊成功

並且,服務調用一切正常。你可能會想:前面講了一堆,你告訴我改了兩行配置就是平滑遷移了?我還是得好好糾正下這種想法,改代碼從來都是最輕鬆的事,難的是在遷移中,時刻觀察業務狀況,確保服務不因爲遷移有損。除此之外,還需要注意的是,Dubbo 自帶的多註冊中心方案因爲框架實現的問題,存在一定的缺陷。

Dubbo 多註冊中心的缺陷

在 Dubbo 的實現中,多個註冊中心的地址是隔離的,地址不會融合。也就是說,當消費者如下配置後:

dubbo.registries.first.protocol=consul
dubbo.registries.first.address=localhost:8500

dubbo.registries.second.protocol=nacos
dubbo.registries.second.address=mse-kirito-p.nacos-ans.mse.aliyuncs.com:8848

會永遠優先從 Consul 中讀取服務地址,除非 Consul 中沒有服務,纔會嘗試從 Nacos 中讀取,順序取決於配置文件中註冊中心聲明的先後。這可能不符合大多數人對多註冊中心的直觀認知,但沒辦法,Dubbo 就是這麼設計的,我也嘗試猜想了幾個這麼設計的可能性:

  • 多個註冊中心沒有感知到對方存在的必要,所以只能串行讀取多個註冊中心

  • Dubbo 本身模型不支持註冊中心聚合,除非專門搞一個 AggregationRegistry 代理多個註冊中心實現

  • 多個註冊地址的 equals 方案難以確定,官方沒有給出契約規範,即 ip 和 port 相同就可以認爲同一個地址嗎?

  • Dubbo 的多註冊中心的設計並不只是爲了適配平滑遷移方案,其他場景可能恰恰希望使用這種串行讀取的策略

爲了讓讀者有一個直觀的感受,我用文末的 demo 進行了測試,讓服務提供者 A1(端口號 12346) 只註冊到 Nacos,服務提供者 A2(端口號爲 12345) 只註冊到 Consul,消費者 B 雙訂閱 Nacos 和 Consul。如下圖所示,在測試初期,可以發現,穩定調用到 A1;期間,我手動 kill 了 A1,圖中也清晰地打印出了一條地址下線通知,之後穩定調用到 A2。

這樣的缺陷,會導致我們在平滑遷移過程中無法對未遷移應用和遷移中應用進行充分的測試。

Dubbo 平滑遷移方案 – 註冊中心聚合

註冊中心聚合這個詞其實是我自己想的,因爲 Dubbo 官方文檔並沒有直接給出這種方案,而是由阿里雲的微服務商業化 EDAS 團隊提供的開源實現(ps,沒錯,就是我所在的團隊啦)。其基本思路就是前文提到的,聚合多個註冊中心的地址。使用方式也同樣簡單

引入依賴:

<dependency>
    <groupId>com.alibaba.edas</groupId>
    <artifactId>edas-dubbo-migration-bom</artifactId>
    <version>2.6.5.1</version>
    <type>pom</type>
</dependency>

增加配置:

在 application.properties 中添加註冊中心的地址。

dubbo.registry.address = edas-migration://30.5.124.15:9999?service-registry=consul://localhost:8500,nacos://mse-kirito-p.nacos-ans.mse.aliyuncs.com:8848&reference-registry=consul://localhost:8500,nacos://mse-kirito-p.nacos-ans.mse.aliyuncs.com:8848

說明 如果是非 Spring Boot 應用,在 dubbo.properties 或者對應的 Spring 配置文件中配置。

  • edas-migration://30.5.124.15:9999
    

    多註冊中心的頭部信息。可以不做更改,ip 和 port 可以任意填寫,主要是爲了兼容 Dubbo 對 ip 和 port 的校驗。啓動時,如果日誌級別是 WARN 及以下,可能會拋一個 WARN 的日誌,可以忽略。

  • service-registry
    

    服務註冊的註冊中心地址。寫入多個註冊中心地址。每個註冊中心都是標準的 Dubbo 註冊中心格式;多個用,分隔。

  • reference-registry
    

    服務訂閱的註冊中心地址。每個註冊中心都是標準的 Dubbo 註冊中心格式;多個用,分隔。

驗證該方案:

已經變成了隨機調用,解決了多註冊中心的缺陷。

遷移完成後,建議刪除原註冊中心的配置和遷移過程專用的依賴edas-dubbo-migration-bom,在業務量較小的時間分批重啓應用。edas-dubbo-migration-bom 是一個遷移專用的依賴,雖然長期使用對您業務的穩定性沒有影響,但其並不會跟隨 Dubbo 的版本進行升級,爲避免今後框架升級過程中出現兼容問題,推薦您在遷移完畢後清理掉,然後在業務量較小的時間分批重啓應用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章