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

1. 概述

可能提及來Dubbo,不少人都不陌生,這畢竟是一款從2012年就開始開源的Java RPC框架,中間因爲各類各樣的緣由中止更新4年半的時間,中間只發過一個小版本修了一個小bug,甚至你們都覺得這個項目已經死掉了,居然又在2017年9月份恢復了更新,不可謂不神奇。java

網絡上不少人都拿Dubbo和Spring Cloud作對比,可能在你們的心目中,這兩個框架是能夠畫上等號的吧,後來在網絡上有一個很是流行的表格,比較詳細的對比了 Spring Cloud 和 Dubbo ,表格以下:git

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的一個子集。github

Dubbo 在國內擁有着巨大的用戶羣,你們但願在使用 Dubbo 的同時享受 Spring Cloud 的生態,出現各類各樣的整合方案,可是由於服務中心的不一樣,各類整合方案並非那麼天然,直到 Spring Cloud Alibaba 這個項目出現,由官方提供了 Nacos 服務註冊中心後,纔將這個問題完美的解決。而且提供了 Dubbo 和 Spring Cloud 整合的方案,命名爲: Dubbo Spring Cloud 。web

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官方文檔。spring

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

1.3 Dubbo Spring Cloud 主要特性

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

1.4 Spring Cloud 爲何須要RPC

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

雖然說在微服務架構中,會講按照業務劃分的微服務獨立部署,而且運行在各自的進程中。微服務之間的通訊更加傾向於使用HTTP這種簡答的通訊機制,大多數狀況都會使用REST API。這種通訊方式很是的簡潔高效,而且和開發平臺、語言無關,可是一般狀況下,HTTP並不會開啓KeepAlive功能,即當前鏈接爲短鏈接,短鏈接的缺點是每次請求都須要創建TCP鏈接,這使得其效率變的至關低下。瀏覽器

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

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 官方文檔

相關文章
相關標籤/搜索