<input id="0qass"><u id="0qass"></u></input>
  • <input id="0qass"><u id="0qass"></u></input>
  • <menu id="0qass"><u id="0qass"></u></menu>

    Dubbo想要個網關怎么辦?試試整合Spring Cloud Gateway

    mark

    一、背景

    在微服務架構中 API網關 非常重要,網關作為全局流量入口并不單單是一個反向路由,更多的是把各個邊緣服務(Web層)的各種共性需求抽取出來放在一個公共的“服務”(網關)中實現,例如安全認證、權限控制、限流熔斷、監控、跨域處理、聚合API文檔等公共功能。

    ?

    在以 Dubbo 框架體系來構建的微服務架構下想要增加API網關,如果不想自研開發的情況下在目前的開源社區中幾乎沒有找到支持dubbo協議的主流網關,但是 Spring Cloud 體系下卻有兩個非常熱門的開源API網關可以選擇;本文主要介紹如何通過 Nacos 整合 Spring Cloud GatewayDubbo 服務。

    ?

    二、傳統 dubbo 架構

    dubbo屬于rpc調用,所以必須提供一個web層的服務作為http入口給客戶端調用,并在上面提供安全認證等基礎功能,而web層前面對接Nginx等反向代理用于統一入口和負載均衡。

    web層一般是根據業務模塊來切分的,用于聚合某個業務模塊所依賴的各個service服務

    file

    PS:我們能否把上圖中的web層全部整合在一起成為一個API網關呢?(不建議這樣做)

    因為這樣的web層并沒有實現 泛化調用 必須引入所有dubbo服務的api依賴,會使得網關變得非常不穩定,任何服務的接口變更都需要修改網關中的api依賴!

    ?

    三、整合 Srping Cloud Gateway 網關

    下面就開始聊聊直接拿熱門的 Srping Cloud Gateway 來作為dubbo架構體系的網關是否可行,首先該API網關是屬于 Spring Cloud 體系下的組件之一,要整合dubbo的話需要解決以下問題:

    1. 打通注冊中心:spring cloud gateway 需要通過注冊中心發現下游服務,而 dubbo 也需要通過注冊中心實現服務的注冊與發現,如果兩者的注冊中心不能打通的話就會變成雙注冊中心架構就非常復雜了!
    2. 協議轉換: gateway 使用http傳輸協議調用下游服務,而dubbo服務默認使用的是tcp傳輸協議

    上面提到的第一個問題“打通注冊中心”其實已經不是問題了,目前dubbo支持 ZookeeperNacos 兩個注冊中心,而 Spring Cloud 自從把 @EnableEurekaClient 改為 @EnableDiscoveryClient 之后已經基本上支持所有主流的注冊中心了,本文將使用 Nacos 作為注冊中心打通兩者

    ?

    3.1. 方式一

    把傳統dubbo架構中的 Nginx 替換為 Spring Cloud Gateway ,并把 安全認證 等共性功能前移至網關處實現
    mark

    由于web層服務本身提供的就是http接口,所以網關層無需作協議轉換,但是由于 安全認證 前移至網關了需要通過網絡隔離的手段防止被繞過網關直接請求后面的web層

    ?

    3.2. 方式二

    dubbo服務本身修改或添加 rest 傳輸協議的支持,這樣網關就可以通過http傳輸協議與dubbo服務通信了

    rest傳輸協議:基于標準的Java REST API——JAX-RS 2.0(Java API for RESTful Web Services的簡寫)實現的REST調用支持

    mark

    目前版本的dubbo已經支持dubbo、rest、rmi、hessian、http、webservice、thrift、redis等10種傳輸協議了,并且還支持同一個服務同時定義多種協議,例如配置 protocol = { “dubbo”, “rest” } 則該服務同時支持 dubborest 兩種傳輸協議

    ?

    3.3. 總結

    方式一 對比 方式二 多了一層web服務所以多了一次網絡調用開銷,但是優點是各自的職責明確單一,web層可以作為聚合層用于聚合多個service服務的結果經過融合加工一并返回給前端,所以這種架構下能大大減少服務的 循環依賴

    ?

    四、代碼實踐

    依賴環境

    • lombok
    • jdk 1.8
    • Nacos 1.3
    • Spring Boot 2.2.8.RELEASE
    • Spring Cloud Hoxton.SR5
    • Spring Cloud Alibaba 2.2.1.RELEASE

    ?

    在根目錄的 pom.xml 中定義全局的依賴版本

        <properties>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <java.version>8</java.version>
    
            <spring-boot-dependencies.version>2.2.8.RELEASE</spring-boot-dependencies.version>
            <spring-cloud-dependencies.version>Hoxton.SR5</spring-cloud-dependencies.version>
            <spring-cloud-alibaba-dependencies.version>2.2.1.RELEASE</spring-cloud-alibaba-dependencies.version>
            <jaxrs.version>3.12.1.Final</jaxrs.version>
        </properties>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>${spring-boot-dependencies.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
    
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud-dependencies.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-dependencies.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    

    ?

    4.1. 創建dubbo-api工程

    分別定義兩個api接口

    DubboService 使用dubbo協議的服務

    public interface DubboService {
        String test(String param);
    }
    

    RestService 使用rest協議的服務

    public interface RestService {
        String test(String param);
    }
    

    ?

    4.2. 創建web-dubbo工程

    使用 方式一 整合對接網關,這里為了簡化在同一個服務下只使用邏輯分層定義controller層與service層,并沒有做服務拆分

    4.2.1. 創建配置

    定義 spring boot 配置

    server:
      port: 8081
    
    spring:
      application:
        name: zlt-web-dubbo
      main:
        allow-bean-definition-overriding: true
      cloud:
        nacos:
          server-addr: 192.168.28.130:8848
          username: nacos
          password: nacos
    

    server.port:配置應用服務器暴露的端口

    spring.cloud.nacos:配置 spring cloud 的注冊中心相關參數,nacos 的配置需要改為自己環境所對應

    定義 dubbo 配置

    dubbo:
      scan:
        base-packages: org.zlt.service
      protocols:
        dubbo:
          name: dubbo
          port: -1
      registry:
        address: spring-cloud://localhost
      consumer:
        timeout: 5000
        check: false
        retries: 0
      cloud:
        subscribed-services:
    

    dubbo.scan.base-packages:指定 Dubbo 服務實現類的掃描基準包

    dubbo.protocols:服務暴露的協議配置,其中子屬性 name 為協議名稱,port 為協議端口( -1 表示自增端口,從 20880 開始)

    dubbo.registry.address:Dubbo 服務注冊中心配置,其中子屬性 address 的值 “spring-cloud://localhost”,說明掛載到 Spring Cloud 注冊中心

    ?

    4.2.2. 創建DubboService的實現類

    通過 protocol = "dubbo" 指定使用 dubbo協議 定義服務

    @Service(protocol = "dubbo")
    public class DubboServiceImpl implements DubboService {
        @Override
        public String test(String param) {
            return "dubbo service: " + param;
        }
    }
    

    ?

    4.2.3. 創建Controller類

    使用 Spring Boot@RestController 注解定義web服務

    @RestController
    public class WebController {
        @Autowired
        private DubboService dubboService;
    
        @GetMapping("/test/{p}")
        public String test(@PathVariable("p") String param) {
            return dubboService.test(param);
        }
    }
    

    ?

    4.3. 創建rest-dubbo工程

    使用 方式二 整合對接網關,由于該服務是通過dubbo來創建rest服務,所以并不需要使用 Spring Boot 內置應用服務

    4.3.1. 創建配置

    定義 spring boot 配置

    spring:
      application:
        name: zlt-rest-dubbo
      main:
        allow-bean-definition-overriding: true
      cloud:
        nacos:
          server-addr: 192.168.28.130:8848
          username: nacos
          password: nacos
    

    因為不使用 Spring Boot 內置的應用服務所以這里并不需要指定 server.port

    定義 dubbo 配置

    dubbo:
      scan:
        base-packages: org.zlt.service
      protocols:
        dubbo:
          name: dubbo
          port: -1
        rest:
          name: rest
          port: 8080
          server: netty
      registry:
        address: spring-cloud://localhost
      consumer:
        timeout: 5000
        check: false
        retries: 0
      cloud:
        subscribed-services:
    

    dubbo.protocols:配置兩種協議,其中rest協議定義 8080 端口并使用 netty 作為應用服務器

    ?

    4.3.2. 創建RestService的實現類

    通過 protocol = "rest" 指定使用 rest協議 定義服務

    @Service(protocol = "rest")
    @Path("/")
    public class RestServiceImpl implements RestService {
        @Override
        @Path("test/{p}")
        @GET
        public String test(@PathParam("p") String param) {
            return "rest service: " + param;
        }
    }
    

    ?

    4.4. 創建Spring Cloud Gateway工程

    定義 spring boot 配置

    server:
      port: 9900
    
    spring:
      application:
        name: sc-gateway
      main:
        allow-bean-definition-overriding: true
      cloud:
        nacos:
          server-addr: 192.168.28.130:8848
          username: nacos
          password: nacos
    

    server.port:定義網關端口為 9090

    定義網關配置

    spring:
      cloud:
        gateway:
          discovery:
            locator:
              lowerCaseServiceId: true
              enabled: true
          routes:
            - id: web
              uri: lb://zlt-web-dubbo
              predicates:
                - Path=/api-web/**
              filters:
                - StripPrefix=1
            - id: rest
              uri: lb://zlt-rest-dubbo
              predicates:
                - Path=/api-rest/**
              filters:
                - StripPrefix=1
    

    分別定義兩個路由策略:

    • 路徑 /api-web/ 為請求 web-dubbo 工程
    • 路徑 /api-rest/ 為請求 rest-dubbo 工程

    ?

    4.5. 測試

    分別啟動:Nacos、sc-gateway、web-dubbo、rest-dubbo 工程,通過網關的以下兩個接口分別測試兩種整合方式

    1. http://127.0.0.1:9900/api-web/test/abc :請求 web-dubbo 工程測試整合方式一
    2. http://127.0.0.1:9900/api-rest/test/abc :請求 rest-dubbo 工程測試整合方式二

    ?

    五、demo下載

    ide需要安裝 lombok 插件

    https://github.com/zlt2000/dubboSpringCloud

    ?
    掃碼關注有驚喜!

    file

    ??2020 CSDN 皮膚主題: 大白 設計師:CSDN官方博客 返回首頁
    多乐彩