溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何升級dubbo2.7.4.1版本平滑遷移到注冊中心nacos

發(fā)布時間:2022-02-24 13:41:14 來源:億速云 閱讀:185 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹“如何升級dubbo2.7.4.1版本平滑遷移到注冊中心nacos”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“如何升級dubbo2.7.4.1版本平滑遷移到注冊中心nacos”文章能幫助大家解決問題。

    前言       

    dubbo是一款非常優(yōu)秀的服務治理型RPC框架,dubbo的優(yōu)秀在于,龐大的架構體系、精湛的模塊設計、靈活的SPI設計、豐富的組件實現(xiàn),博主做微服務技術選型考察dubbo時,非常驚嘆在那個年代別人就已經(jīng)能夠產(chǎn)出如此優(yōu)秀的項目,以至于后面每逢別人說想要學習架構設計時,我都會推薦他讀讀dubbo的代碼,學習下dubbo的架構設計原則。常說dubbo不僅僅是一款RPC框架,是因為他的服務治理特性相對于RPC通訊來說更加的突出,這個特性讓我在2017年選型的時候果斷選擇了他,那個時候dubbo官方還沒產(chǎn)出spring boot starter,而我們的項目大部分完成了從spring mvc改造到spring boot項目。為了簡化開發(fā)集成dubbo組件,我們基于dubbo2.5.6版本自研了一套spring-boot-dubbo-starter組件,并且自定義dubbo服務暴露和引入的注解, 自定義了dubbo的配置裝載方式。當時沒有專業(yè)的運維、搭建高可用zk也費資源,為了簡單方便少維護一個組件、當時我們直接選了redis(阿里云高可用實例)作為dubbo的注冊中心。以上就是我們這次升級dubbo的背景情況

    為什么升級到2.7.4.1?

    從2.5.6到2.7.x,中間修復非常多的bug,帶來了非常多的新特性。

    2.5.x版本不在作為一個保留維護的版本,目前主力維護的就2.6.x和2.7.x版本,還有探索版本3.0.也就是說即使2.5.x以后有問題了,官方也不會在修復了。

    之所以選擇2.7.4.1版本,是因為經(jīng)過研究了官方issue和關注了dubbo群里的情況后,發(fā)現(xiàn)這個版本相對比較穩(wěn)定,而且官方也推薦升級到這個版本。

    為什么遷移注冊中心到nacos?

    目前redis注冊中心雖然經(jīng)過了趟坑之后《dubbo使用redis注冊中心的系列問題》,趨于穩(wěn)定了,但是因為太小眾,使用的人太少導致很多問題并沒有暴露出來(在升級的過程中又發(fā)現(xiàn)了一個redis注冊中心的問題), 如果繼續(xù)使用redis注冊中心,將會一直處在不斷自我趟坑的過程中無法自拔。

    nacos是dubbo官方主推的注冊中心項目,雖然現(xiàn)在還在迭代磨合,但是一旦發(fā)現(xiàn)問題官方反應還是比較及時的。使用nacos人越來越多,相當于趟坑的人也多了,隱藏的bug就無處可藏了。而且nacos和dubbo有天生的血緣關系, 查看nacos近期的release情況,發(fā)現(xiàn)有幾個特意修復dubbo注冊的問題

    nacos自帶了web管理控制臺,可以非常方便的查詢dubbo的注冊情況,可以作為一個簡易的dubbo治理中心來使用

    兩種升級方案

    由于我們目前維護了自己的spring-boot-dubbo-starter,所以在做升級時,我們產(chǎn)生了兩種不同的升級方案,并且都做了完整的驗證。

    方案一:魔改官方的starter組件

    為了做到開發(fā)側基本無感知升級到2.7.4.1版本,我們做了兩件事情

    注解兼容

    在做注解兼容時也考慮過兩個方案,一個是在自研的starter上做兼容dubbo2.7.4.1的處理,一個是在官方2.7.4.1的starter上兼容我們的處理。后面果斷選擇了后者,因為dubbo2.7.4.1版本對于我們來說是個黑盒子不知道有哪些改動,正向兼容難度比較大,反向兼容卻要容易的多。 我們將原來自研組件里的自定義注解,保留包路徑完整的拷貝到官方的starter項目中,然后將 ReferenceAnnotationBeanPostProcessor和ServiceAnnotationBeanPostProcessor從dubbo的spring模塊中挪了出來,做了兼容自定義注解的處理。這個地方再次夸下 dubbo的設計,dubbo在捐贈給apache后,包名都改了,為了兼容老的alibaba包下的注解,服務暴露和服務引入都做了非常簡易的注解兼容設計。 得益于此,我們在做自定義注解兼容處理時非常輕松就搞定了。

    ReferenceAnnotationBeanPostProcessor的構造器傳入自定義注解:

    public ReferenceAnnotationBeanPostProcessor() {
            super(AutowiredDubbo.class, Reference.class, com.alibaba.dubbo.config.annotation.Reference.class);
        }

    ServiceAnnotationBeanPostProcessor掃描時添加自定義注解支持 

    scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class));
            /**
             * Add the compatibility for legacy Dubbo's @Service
             *
             * The issue : https://github.com/apache/dubbo/issues/4330
             * @since 2.7.3
             */
            scanner.addIncludeFilter(new AnnotationTypeFilter(com.alibaba.dubbo.config.annotation.Service.class));
            // 兼容@DubboService注解
            scanner.addIncludeFilter(new AnnotationTypeFilter(DubboService.class));

    最后修改DubboAutoConfiguration中的服務暴露和服務引入處理器為我們魔改的實現(xiàn)即可

    配置兼容

    自研的自定義配置加載以spring.dubbo.打頭的,而官方是以dubbo.打頭的,區(qū)別如下:

    自研的配置:
    spring.dubbo.application.name = xxx
    spring.dubbo.registry.address = xxx
    spring.dubbo.protocol.port = -1
    官方starter配置
    dubbo.application.name = xxx
    dubbo.registry.address = xxx
    dubbo.protocol.port = -1

    為了做到配置兼容,修改了dubbo starter配置加載邏輯,去掉了spring.打頭,修改DubboUtils中的filterDubboProperties,如:

    public static SortedMap filterDubboProperties(ConfigurableEnvironment environment) {
            SortedMap dubboProperties = new TreeMap<>();
            Map properties = EnvironmentUtils.extractProperties(environment);
            for (Map.Entry entry : properties.entrySet()) {
                String propertyName = entry.getKey();
                if (propertyName.startsWith(DUBBO_PREFIX + PROPERTY_NAME_SEPARATOR)
                        && entry.getValue() != null) {
                    dubboProperties.put(propertyName, entry.getValue().toString());
                }
                if (propertyName.startsWith("spring." + DUBBO_PREFIX + PROPERTY_NAME_SEPARATOR)
                        && entry.getValue() != null) {
                    propertyName = propertyName.substring(7);
                    dubboProperties.put(propertyName, entry.getValue().toString());
                }
            }
            return Collections.unmodifiableSortedMap(dubboProperties);
        }

    最后打包上傳到私服,開發(fā)只需要升級下jar的版本,配置和代碼都不用動就可以升級到2.7.4.1版本的dubbo,可能魔改的地方不止上面貼的這些代碼,這里只是引出思路,這個方案到這里結束了,這個方案的優(yōu)點是對開發(fā)比較透明 因為遷移到nacos的步驟是一樣的,第二個方案會談到

    方案二:直接使用官方的starter組件-最終采用的方案

    最終討論下來,考慮到內(nèi)部維護版本,當官方升級時聯(lián)動升級會比較麻煩,不如,直接痛一次全線改造代碼,改造配置,采用了官方的starter直接升級,這樣,后面有版本升級不用在投入人力維護自研的和官方的一致。

    第一步:引入maven依賴

    官方dubbo starter依賴

    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.4.1</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba.nacos</groupId>
        <artifactId>nacos-client</artifactId>
        <version>1.1.3</version>
    </dependency>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
    </dependency>
    第二步:改造相關的注解

    啟用dubbo時:@EnableDubbo 改成

    @EnableDubbo【org.apache.dubbo.config.spring.context.annotation.EnableDubbo】

    并建議添加scanBasePackages包路徑,如:

    @EnableDubbo(scanBasePackages = "cn.keking.service")。

    提高dubbo暴露服務和引入服務時的掃描速度

    服務暴露時:

    @DubboService 改成 @Service 【org.apache.dubbo.config.annotation.Service】

    服務引入時:

    @AutowiredDubbo 改成 @Reference 【org.apache.dubbo.config.annotation.Reference】,

    這里需要注意三點:

    1、官方的starter默認的服務引入會校驗服務是否存在,不存在就拋異常,會影響應用啟動,可添加全局的配置,覆蓋默認行為,配置如下:dubbo.consumer.check=false

    2、自研starter中@AutowiredDubbo 的timeout等參數(shù)的單位為秒,官方注解@Reference的參數(shù)單位為毫秒,如以前配置為timeout=30, 則在官方starter中只有30毫秒的超時時間。

    3、在使用多注冊中心時,dubbo會從兩個注冊中心同時引入服務,雖然你的URL是完全一樣的,也會在本地產(chǎn)生兩個服務實例,所以,當你的容錯模式為廣播模式(cluster="Broadcast")或者并行模式(cluster="Forking")時就會產(chǎn)生消費者一次觸發(fā),生產(chǎn)者收到兩次的問題。而默認的集群策略為 Failover,會正常的走隨機負載的方式調(diào)用,不會有這種問題。如果有廣播模式、或者并行模式的使用,可以通過設置nacos注冊中心,只注冊不消費。配置方式如下,等所以服務都遷移到nacos上后及時移除這個配置:

    dubbo.registries.nacos.parameters.subscribe = false

    第三步:修改dubbo的配置

    去掉spring.前綴即可,注意,升級官方starter后,需要新增一個配置,用來設置redis的連接池大小,官方默認的8個, 

    dubbo.registries.redis.parameters.max.total = 200

    下面示例了升級后的dubbo配置:

    dubbo.application.name = xxx
    dubbo.protocol.port = -1
    dubbo.provider.timeout = 300000
    dubbo.consumer.check = false
    dubbo.registries.nacos.address = nacos://xxx:80
    dubbo.registries.redis.address = redis://xxx:6379
    dubbo.registries.redis.parameters.max.total = 200

    平滑遷移到nacos注冊中心

    利用dubbo支持多注冊中心的功能,分兩個階段完成平滑的從redis遷移到nacos,第一階段,全線升級修改配置為雙注冊中心,第二階段,摘掉redis注冊中心完成過渡,配置方式如下:

    dubbo.registries.nacos.address=nacos://xxx:80
    dubbo.registries.redis.address=redis://xx:6379

    注意一些問題

    使用redis注冊中心時,如果只有一個redis實例,區(qū)分環(huán)境是通過redis的db來控制的,比如如下配置:

    dubbo.registry.parameters.db.index = 2

    而nacos注冊中心通過命名空間來區(qū)分的,具體配置如下:

    dubbo.registry.parameters.namespace = xxxxxx

    如果是多注冊中心配置,注意使用相關注冊中心前綴,比如:

    dubbo.registries.nacos.parameters.namespace=adefa98f-f4d9-4af8-9eb3-e0cab5a39cc7

    關于“如何升級dubbo2.7.4.1版本平滑遷移到注冊中心nacos”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識,可以關注億速云行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

    AI