SpringCloud系列之Nacos+Dubbo應用篇

吳碼發表於2020-09-04

前言

本文在前篇文章《SpringCloud系列之Nacos應用篇》基礎上整合Dubbo,公司專案中新專案採用SpringCloud(後續會逐漸替換至spring cloud alibaba全家桶),老專案採用傳統SSM+Dubbo,部分業務上新老專案都有所涉及,原先少許業務上是直接通過http請求來處理新老專案互動的,總覺得這樣做不夠優雅,也不利於維護,於是自己調研調研看。
在前篇《SpringCloud系列之整合Dubbo應用篇》文章中Dubbo是依託zookeeper作為服務註冊發現元件,這次專案中以SpirngCloud,Nacos,Dubbo三者整合起來,減少了Eureka、SpringConfig、zookeeper元件的投入,配置、服務註冊發現都依賴Nacos服務,減少維護工作,死磕Nacos即可。

專案版本

spring-boot-version:2.2.5.RELEASE
spring-cloud.version:Hoxton.SR3
nacos.version:1.3.2
dubbo.version:2.6.9/2.7.6

專案說明

新專案模組間採用Feign進行相互互動,老專案模組間採用Dubbo進行互動,新老專案間採用Dubbo互動。在整合Dubbo時也針對Dubbo 2.6.x及Dubbo 2.7.x版本進行分別說明。

當然也可以都用Dubbo進行互動。

涉及Nacos配置資訊,請查閱上篇文章《SpringCloud系列之Nacos應用篇》,本文只涉及新增Dubbo相關的配置,完整專案原始碼請檢視本文文末專案原始碼。

專案結構

專案分支付模組和使用者模組,支付模組提供Dubbo服務供使用者模組消費,使用者模組提供Feign服務供支付模組呼叫。

整合Dubbo2.6.x

整合Dubbo2.6.x系列版本中費了不少時間,主要涉及nacos-client版本中不同版本有些類所屬包發生了變更,導致整合時提示找不到類,自己嘗試調整了下依賴的版本,最終要麼這個版本有這個問題,另外一個版本又有另一個問題,都不能很好解決,心想不會就這麼涼涼了吧
常見問題如下
java.lang.NoClassDefFoundError: com/alibaba/nacos/client/naming/utils/StringUtils
java.lang.NoClassDefFoundError: com/alibaba/nacos/api/naming/NamingMaintainService
後來在Nacos Github上看到了這條issues,發現基本是同樣的問題,就按照以下版本測試了下,居然成功了,後來又在此依賴版本上對相應版本進行了升級。
https://github.com/alibaba/nacos/issues/2022

最終依賴如下
pom.xml

        <!--nacos discovery-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--nacos config-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--dubbo-->
        <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.9</version>
        </dependency>
        <!--dubbo nacos-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo-registry-nacos</artifactId>
            <version>2.6.7</version>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--nacos-->
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.31.Final</version>
        </dependency>

支付模組

application.properties

Dubbo 2.6.x 系列需在Dubbo配置項中增加dubbo.application.name配置項,不然再啟動時會提示缺少該配置項

dubbo.application.name=pay-service
# dubbo掃描包路徑
dubbo.scan.base-packages=com.chinawu.cloud.pay.service
# dubbo協議
dubbo.protocol.name=dubbo
# 隨機埠
dubbo.protocol.port=-1
# zookeeper地址
dubbo.registry.address=nacos://127.0.0.1:8848

DPayService.java

@Service為Dubbo註解,import com.alibaba.dubbo.config.annotation.Service;

@Service
public class DPayService implements DPayFacade {

    @Override
    public String goToPay(String userName) {
        System.out.println("dubbo.method:goToPay request "+userName);
        return "dubbo.method:goToPay result:" + userName + " pay success";
    }
}

PayServiceApplication.java

SpringBoot 啟動類需增加 @EnableDubbo 註解標籤,不然服務沒法暴露,註冊

@SpringBootApplication
@EnableDiscoveryClient
@EnableAutoConfiguration
@EnableFeignClients(basePackages = {"com.chinawu.cloud.user.*"})
@EnableDubbo
public class PayServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(PayServiceApplication.class, args);
    }

}

使用者模組

application.properties

dubbo.application.name=user-service
# dubbo掃描包路徑
dubbo.scan.base-packages=com.chinawu.cloud.user.service
# dubbo協議
dubbo.protocol.name=dubbo
# 隨機埠
dubbo.protocol.port=-1
# zookeeper地址
dubbo.registry.address=nacos://127.0.0.1:8848

UserController.java

@RestController
@RequestMapping("/user")
@RefreshScope
public class UserController {

    @Value("${spring.datasource.url}")
    private String datasourceUrl;

    // Dubbo服務消費
    @Reference(check = false)
    DPayFacade dPayFacade;


    /**
     * <p >
     * 功能:獲取資料來源連線配置資訊
     * </p>
     * @param
     * @author wuyubin
     * @date  2020年9月3日
     * @return
     */
    @RequestMapping("/getDatasourceUrl")
    public String getDatasourceUrl() {
        return datasourceUrl;
    }

    /**
     * <p >
     * 功能:測試Dubbo服務呼叫
     * </p>
     * @param
     * @author wuyubin
     * @date  2020年9月3日
     * @return
     */
    @RequestMapping("/goToPay")
    public String goToPay() {
        return dPayFacade.goToPay("wuyubin");
    }
}

整合Dubbo2.7.x

整合Dubbo2.7.x系列版本,相比就簡單不少,直接引入如下依賴
pom.xml

		<!--nacos discovery-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--nacos config-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--dubbo-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.8</version>
        </dependency>
        <!--dubbo nacos-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo-registry-nacos</artifactId>
            <version>2.7.6</version>
            <exclusions>
                <exclusion>
                    <groupId>com.alibaba.nacos</groupId>
                    <artifactId>nacos-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--nacos-->
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.3.2</version>
        </dependency>

支付模組

application.properties

# dubbo掃描包路徑
dubbo.scan.base-packages=com.chinawu.cloud.pay.service
# dubbo協議
dubbo.protocol.name=dubbo
# 隨機埠
dubbo.protocol.port=-1
# zookeeper地址
dubbo.registry.address=nacos://127.0.0.1:8848

DPayService.java

@Service 為Dubbo註解,import org.apache.dubbo.config.annotation.Service;

@Service
public class DPayService implements DPayFacade {

    @Override
    public String goToPay(String userName) {
        System.out.println("dubbo.method:goToPay request "+userName);
        return "dubbo.method:goToPay result:" + userName + " pay success";
    }
}

使用者模組

application.properties

# dubbo掃描包路徑
dubbo.scan.base-packages=com.chinawu.cloud.user.service
# dubbo協議
dubbo.protocol.name=dubbo
# 隨機埠
dubbo.protocol.port=-1
# zookeeper地址
dubbo.registry.address=nacos://127.0.0.1:8848

UserController.java

@RestController
@RequestMapping("/user")
@RefreshScope
public class UserController {

    @Value("${spring.datasource.url}")
    private String datasourceUrl;
    // Dubbo服務消費
    @Reference(check = false)
    DPayFacade dPayFacade;

    /**
     * <p >
     * 功能:獲取資料來源連線配置資訊
     * </p>
     * @param
     * @author wuyubin
     * @date  2020年9月3日
     * @return
     */
    @RequestMapping("/getDatasourceUrl")
    public String getDatasourceUrl() {
        return datasourceUrl;
    }

    /**
     * <p >
     * 功能:測試Dubbo服務呼叫
     * </p>
     * @param
     * @author wuyubin
     * @date  2020年9月3日
     * @return
     */
    @RequestMapping("/goToPay")
    public String goToPay() {
        return dPayFacade.goToPay("wuyubin");
    }
}

測試驗證

支付模組和使用者模組都啟動後,我們進入Nacos後臺進行檢視,發現服務都已註冊上,如下圖

請求下使用者模組預留的介面(內部通過Dubbo請求支付模組),如下圖
http://localhost:9012/user/goToPay

請求下支付模組預留的介面(內部通過Feign請求使用者模組),如下圖
http://localhost:9011/pay/get

至此Nacos和Dubbo已整合至SpringCloud。

參考資料

https://github.com/alibaba/spring-cloud-alibaba
https://nacos.io/zh-cn/docs/use-nacos-with-dubbo.html

系列文章

SpringCloud系列之配置中心(Config)使用說明

SpringCloud系列之服務註冊發現(Eureka)應用篇

SpringCloud系列之閘道器(Gateway)應用篇

SpringCloud系列之整合Dubbo應用篇

SpringCloud系列之整合分散式事務Seata應用篇

SpringCloud系列之Nacos應用篇

專案原始碼

在這裡插入圖片描述

相關文章