SpringCloud系列之Nacos+Dubbo應用篇

前言

本文在前篇文章《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,發現基本是同樣的問題,就按照以下版本測試了下,居然成功了,後來又在此依賴版本上對相應版本進行了升級。
//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請求支付模塊),如下圖
//localhost:9012/user/goToPay

請求下支付模塊預留的接口(內部通過Feign請求用戶模塊),如下圖
//localhost:9011/pay/get

至此Nacos和Dubbo已整合至SpringCloud。

參考資料

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

系列文章

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

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

SpringCloud系列之網關(Gateway)應用篇

SpringCloud系列之集成Dubbo應用篇

SpringCloud系列之集成分佈式事務Seata應用篇

SpringCloud系列之Nacos應用篇

項目源碼

在這裡插入圖片描述