Spring Cloud Alibaba | Dubbo 與 Spring Cloud 完美結合


Dubbo 與 Spring Cloud 完美結合

1. 概述

可能說起來Dubbo,很多人都不陌生,這畢竟是一款從2012年就開始開源的Java RPC框架,中間由於各種各樣的原因停止更新4年半的時間,中間只發過一個小版本修了一個小bug,甚至大家都以為這個項目已經死掉了,竟然又在2017年9月份恢復了更新,不可謂不神奇。

網絡上很多人都拿Dubbo和Spring Cloud做對比,可能在大家的心目中,這兩個框架是可以畫上等號的吧,后來在網絡上有一個非常流行的表格,比較詳細的對比了 Spring Cloud 和 Dubbo ,表格如下:

Dubbo SpringCloud
服務注冊中心 Zookeeper Spring Cloud Netfix Eureka
服務調用方式 RPC REST API
服務監控 Dubbo-monitor Spring Boot Admin
熔斷器 不完善 Spring Cloud Netflix Hystrix
服務網關 Spring Cloud Netflix Zuul
分布式配置 Spring Cloud Config
服務跟蹤 Spring Cloud Sleuth
數據流 Spring Cloud Stream
批量任務 Spring Cloud Task
信息總線 Spring Cloud Bus

以上列舉了一些核心部件,當然這里需要申明一點,Dubbo對於上表中總結為“無”的組件不代表不能實現,而只是Dubbo框架自身不提供,需要另外整合以實現對應的功能,這樣看起來確實Dubbo更像是Spring Cloud的一個子集。

Dubbo 在國內擁有着巨大的用戶群,大家希望在使用 Dubbo 的同時享受 Spring Cloud 的生態,出現各種各樣的整合方案,但是因為服務中心的不同,各種整合方案並不是那么自然,直到 Spring Cloud Alibaba 這個項目出現,由官方提供了 Nacos 服務注冊中心后,才將這個問題完美的解決。並且提供了 Dubbo 和 Spring Cloud 整合的方案,命名為: Dubbo Spring Cloud 。

1.2 Dubbo Spring Cloud 概述

Dubbo Spring Cloud 構建在原生的 Spring Cloud 之上,其服務治理方面的能力可認為是 Spring Cloud Plus, 不僅完全覆蓋 Spring Cloud 原生特性,而且提供更為穩定和成熟的實現,特性比對如下表所示:

功能組件 Spring Cloud Dubbo Spring Cloud
分布式配置(Distributed configuration) Git、Zookeeper、Consul、JDBC Spring Cloud 分布式配置 + Dubbo 配置中心
服務注冊與發現(Service registration and discovery) Eureka、Zookeeper、Consul Spring Cloud 原生注冊中心 + Dubbo 原生注冊中心
負載均衡(Load balancing) Ribbon(隨機、輪詢等算法) Dubbo 內建實現(隨機、輪詢等算法 + 權重等特性)
服務熔斷(Circuit Breakers) Spring Cloud Hystrix Spring Cloud Hystrix + Alibaba Sentinel 等
服務調用(Service-to-service calls) Open Feign、RestTemplate Spring Cloud 服務調用 + Dubbo @Reference
鏈路跟蹤(Tracing) Spring Cloud Sleuth + Zipkin Zipkin、opentracing 等

以上對比表格摘自Dubbo Spring Cloud官方文檔。

而且Dubbo Spring Cloud 基於 Dubbo Spring Boot 2.7.1 和 Spring Cloud 2.x 開發,無論開發人員是 Dubbo 用戶還是 Spring Cloud 用戶, 都能輕松地駕馭,並以接近“零”成本的代價使應用向上遷移。Dubbo Spring Cloud 致力於簡化雲原生開發成本,以達成提高研發效能以及提升應用性能等目的。

1.3 Dubbo Spring Cloud 主要特性

  • 面向接口代理的高性能RPC調用:提供高性能的基於代理的遠程調用能力,服務以接口為粒度,屏蔽了遠程調用底層細節。
  • 智能負載均衡:內置多種負載均衡策略,智能感知下游節點健康狀況,顯著減少調用延遲,提高系統吞吐量。
  • 服務自動注冊與發現:支持多種注冊中心服務,服務實例上下線實時感知。
  • 高度可擴展能力:遵循微內核+插件的設計原則,所有核心能力如Protocol、Transport、Serialization被設計為擴展點,平等對待內置實現和第三方實現。
  • 運行期流量調度:內置條件、腳本等路由策略,通過配置不同的路由規則,輕松實現灰度發布,同機房優先等功能。
  • 可視化的服務治理與運維:提供豐富服務治理、運維工具:隨時查詢服務元數據、服務健康狀態及調用統計,實時下發路由策略、調整配置參數。

1.4 Spring Cloud 為什么需要RPC

在Spring Cloud構建的微服務系統中,大多數的開發者使用都是官方提供的Feign組件來進行內部服務通信,這種聲明式的HTTP客戶端使用起來非常的簡潔、方便、優雅,但是有一點,在使用Feign消費服務的時候,相比較Dubbo這種RPC框架而言,性能堪憂。

雖說在微服務架構中,會講按照業務划分的微服務獨立部署,並且運行在各自的進程中。微服務之間的通信更加傾向於使用HTTP這種簡答的通信機制,大多數情況都會使用REST API。這種通信方式非常的簡潔高效,並且和開發平台、語言無關,但是通常情況下,HTTP並不會開啟KeepAlive功能,即當前連接為短連接,短連接的缺點是每次請求都需要建立TCP連接,這使得其效率變的相當低下。

對外部提供REST API服務是一件非常好的事情,但是如果內部調用也是使用HTTP調用方式,就會顯得顯得性能低下,Spring Cloud默認使用的Feign組件進行內部服務調用就是使用的HTTP協議進行調用,這時,我們如果內部服務使用RPC調用,對外使用REST API,將會是一個非常不錯的選擇,恰巧,Dubbo Spring Cloud給了我們這種選擇的實現方式。

2. 實戰

本小結將會以一個簡單的入門案例,介紹一下在使用Nacos作為服務中心,使用Dubbo來實現服務提供方和服務消費方的案例。

Nacos的安裝、部署配置和使用已經在前面的章節介紹過了,這里不再贅述,如果還有不清楚的讀者,請參考前面的Nacos系列文章:

《Spring Cloud Alibaba | Nacos服務中心初探》

《Spring Cloud Alibaba | Nacos服務注冊與發現》

《Spring Cloud Alibaba | Nacos集群部署》

《Spring Cloud Alibaba | Nacos配置管理》

2.1 創建父工程 dubbo-spring-cloud-demo

父工程依賴pom.xml如下:

代碼清單:Alibaba/dubbo-spring-cloud-demo/pom.xml


<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring-cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Dubbo Spring Cloud Starter -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-dubbo</artifactId>
    </dependency>
    <!-- Spring Cloud Nacos Service Discovery -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

注意:

  1. 必須包含spring-boot-starter-actuator包,不然啟動會報錯。

  2. spring-cloud-starter-dubbo包需要注意groupId,根據具體使用的spring cloud alibaba版本依賴來確定。

    • 如果使用孵化版本,使用的groupId為:org.springframework.cloud
    • 如果使用畢業版本,使用的groupId為:com.alibaba.cloud
  3. 以上引用未指定版本,需顯示的聲明<dependencyManagement>

2.2 創建子工程 dubbo_api

API模塊,存放Dubbo服務接口和模型定義,非必要,這里創建僅為更好的代碼重用以及接口、模型規格控制管理。

定義抽象接口HelloService.java:

代碼清單:Alibaba/dubbo-spring-cloud-demo/dubbo_api/src/main/java/com/springcloud/dubbo_api/service/HelloService.java


public interface HelloService {
    String hello(String name);
}

2.3 創建子工程 dubbo_provider ,Dubbo服務提供方

工程依賴pom.xml如下:

代碼清單:Alibaba/dubbo-spring-cloud-demo/dubbo_provider/pom.xml


<!-- API -->
<dependency>
    <groupId>com.springcloud.book</groupId>
    <artifactId>ch13_1_dubbo_api</artifactId>
    <version>${project.version}</version>
</dependency>

此處引入公共API模塊。

實現Dubbo接口,HelloServiceI.java如下:

代碼清單:Alibaba/dubbo-spring-cloud-demo/dubbo_provider/src/main/java/com/springcloud/dubbo_provider/service/HelloServiceI.java


@Service
public class HelloServiceI implements HelloService {
    @Override
    public String hello(String name) {
        return "Hello " + name;
    }
}

注意:這里的@Service注解並不是來自Spring的org.springframework.stereotype.Service,而是Dubbo的org.apache.dubbo.config.annotation.Service,千萬不要引用錯誤。這里的@Service注解僅聲明該Java服務(本地)實現為Dubbo服務。

配置文件 application.yml 需要將Java服務(本地)配置為 Dubbo 服務(遠程)如下:

代碼清單:Alibaba/dubbo-spring-cloud-demo/dubbo_provider/src/main/resources/application.yml


server:
port: 8000
dubbo:
    scan:
        base-packages: com.springcloud.book.ch13_1_dubbo_provider.service
protocol:
    name: dubbo
    port: -1
registry:
    address: spring-cloud://192.168.44.129
spring:
application:
    name: dubbo-spring-cloud-provider
cloud:
    nacos:
    discovery:
        server-addr: 192.168.44.129:8848
main:
    allow-bean-definition-overriding: true

注意:在暴露Dubbo服務方面,推薦使用外部化配置的方式,即指定Java服務實現類的掃描基准包。

Dubbo Spring Cloud 繼承了 Dubbo Spring Boot 的外部化配置特性,也可以通過標注 @DubboComponentScan 來實現基准包掃描。

  • dubbo.scan.base-packages:指定 Dubbo 服務實現類的掃描基准包
  • dubbo.protocol:Dubbo服務暴露的協議配置,其中子屬性name為協議名稱,port為協議端口(-1 表示自增端口,從 20880 開始)
  • dubbo.registry:Dubbo 服務注冊中心配置,其中子屬性address 的值 "spring-cloud://192.168.44.129",說明掛載到 Spring Cloud 注冊中心
  • spring.application.name:Spring 應用名稱,用於 Spring Cloud 服務注冊和發現。該值在 Dubbo Spring Cloud 加持下被視作dubbo.application.name,因此,無需再顯示地配置dubbo.application.name
  • spring.main.allow-bean-definition-overriding:在 Spring Boot 2.1 以及更高的版本增加該設定,因為 Spring Boot 默認調整了 Bean 定義覆蓋行為。
  • spring.cloud.nacos.discovery:Nacos 服務發現與注冊配置,其中子屬性 server-addr 指定 Nacos 服務器主機和端口。

創建應用主類Ch131DubboProviderApplication.java:

代碼清單:Alibaba/dubbo-spring-cloud-demo/dubbo_provider/src/main/java/com/springcloud/dubbo_provider/DubboProviderApplication.java


@SpringBootApplication
@EnableDiscoveryClient
public class DubboProviderApplication {

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

}

2.4 創建子工程 dubbo_consumer ,服務調用方:

工程依賴pom.xml如下:

代碼清單:Alibaba/dubbo-spring-cloud-demo/dubbo_consumer/pom.xml


<!-- API -->
<dependency>
    <groupId>com.springcloud.book</groupId>
    <artifactId>ch13_1_dubbo_api</artifactId>
    <version>${project.version}</version>
</dependency>

工程配置application.yml如下:

代碼清單:Alibaba/dubbo-spring-cloud-demo/dubbo_consumer/src/main/resources/application.yml


server:
port: 8080
dubbo:
protocol:
    name: dubbo
    port: -1
registry:
    address: spring-cloud://192.168.44.129
cloud:
    subscribed-services: dubbo-spring-cloud-provider
spring:
application:
    name: dubbo-spring-cloud-consumer
cloud:
    nacos:
    discovery:
        server-addr: 192.168.44.129:8848
main:
    allow-bean-definition-overriding: true
  • dubbo.cloud.subscribed-services:表示要訂閱服務的服務名,可以配置'*',代表訂閱所有服務,不推薦使用。若需訂閱多應用,使用 "," 分割。

測試接口HelloController.java如下:

代碼清單:Alibaba/dubbo-spring-cloud-demo/dubbo_consumer/src/main/java/com/springcloud/dubbo_consumer/controller/HelloController.java


@RestController
public class HelloController {
    @Reference
    private HelloService helloService;

    @GetMapping("/hello")
    public String hello() {
        return helloService.hello("Dubbo!");
    }
}

注意:這里的@Reference注解是org.apache.dubbo.config.annotation.Reference

啟動主類Ch131DubboConsumerApplication.java如下:

代碼清單:Alibaba/dubbo-spring-cloud-demo/dubbo_consumer/src/main/java/com/springcloud/dubbo_consumer/DubboConsumerApplication.java


@SpringBootApplication
@EnableDiscoveryClient
public class DubboConsumerApplication {

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

}

2.5 測試

啟動子工程 dubbo_provider 和子工程 dubbo_consumer ,啟動完成后,我們可以訪問Nacos控制台的服務列表上看到兩個服務,如圖:

我們打開瀏覽器訪問:http://localhost:8080/hello ,可以看到頁面正常顯示Hello Dubbo!,測試成功,如圖:

3. 示例代碼

示例代碼-Github

示例代碼-Gitee

4. 參考

Dubbo Spring Cloud 官方文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM