資(zī)訊

精準傳達 • 有效溝通

從品牌網站建設到網絡營銷策劃,從策略到執行的一(yī)站式服務

Spring Cloud Gateway實戰之二:更多路由配置方式

來源:公司資(zī)訊 | 2021.08.17

本文是《Spring Cloud Gateway實戰》系列的第二篇,經過前文我(wǒ)們了解到Spring Cloud Gateway的中(zhōng)心是路由裝備,然後在本地application.yml中(zhōng)裝備了一(yī)條路由,但這種修改本地裝備文件的辦法缺少靈敏性,未必能滿意靈敏多變的事務需求,因此,本篇的意圖就是找出本地裝備之外(wài)的其他裝備辦法來,滿意各種實踐需求;
總的來說以下(xià)三種辦法都是常用的:
方針地址支撐用服務名(替代之前的IP+端口);
支撐在nacos上裝備;
支撐寫代碼的辦法裝備;
别的還有一(yī)種愈加靈敏的裝備辦法:動态署理,由于涉及到不少的代碼所以會單獨出一(yī)篇文章詳細介紹
源碼下(xià)載
本篇實戰中(zhōng)的完整源碼可在GitHub下(xià)載到,地址和鏈接信息如下(xià)表所示(https://github.com/zq2599/blog_demos):
名稱 鏈接 備注
項目主頁 https://github.com/zq2599/blog_demos 該項目在GitHub上的主頁
git庫房地址(https) https://github.com/zq2599/blog_demos.git 該項目源碼的庫房地址,https協議
git庫房地址(ssh) git@github.com:zq2599/blog_demos.git 該項目源碼的庫房地址,ssh協議
這個git項目中(zhōng)有多個文件夾,本篇的源碼在spring-cloud-tutorials文件夾下(xià),如下(xià)圖紅框所示:

準備工(gōng)作
正式開(kāi)端前需要再做一(yī)點準備工(gōng)作,整個《Spring Cloud Gateway實戰》系列中(zhōng),一(yī)切請求最後都會被路由到provider-hello這個web上去(qù),該服務現在隻有一(yī)個web接口/hello/str,現在我(wǒ)們再給它添加一(yī)個,後邊的實戰會用到
新添加的web接口來自LBTest.java,可見非常簡略:
package com.bolingcavalry.provider.controller;

import com.bolingcavalry.common.Constants;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.Date;

@RestController
@RequestMapping("/lbtest")
public class LBTest {

    private String dateStr(){
        return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
    }

    /**
     * 回來字符串類型
     * @return
     */
    @GetMapping("/str")
    public String helloStr() {
        return Constants.LB_PREFIX + ", " + dateStr();
    }
}

上述代碼中(zhōng)的Constants.LB_PREFIX來自子工(gōng)程common:
package com.bolingcavalry.common;

public interface Constants {
    String HELLO_PREFIX = "Hello World";
    String LB_PREFIX = "Load balance";
}

寫完代碼後,先保證nacos現已發動
在發動provider-hello工(gōng)程,發動成功後去(qù)看nacos,承認現已注冊:

準備結束,可以開(kāi)端實戰了
方針地址支撐用服務名(替代之前的IP+端口)
我(wǒ)們從最簡略的開(kāi)端,先看前文的路由裝備,如下(xià)圖紅框,方針地址是IP+端口:

玩過Spring Cloud的您天然看出了問題所在:沒有注冊發現,确實,這樣将地址和端口寫死在裝備文件中(zhōng)是不合适的,我(wǒ)們先來處理這個問題;
新增名爲gateway-by-loadbalance的子工(gōng)程,其pom.xml中(zhōng)的依靠情況如下(xià),可見重點是spring-cloud-starter-loadbalancer:

       
           com.bolingcavalry
           common
           ${project.version}
       
       
           org.springframework.cloud
           spring-cloud-starter-gateway
       
       
           io.projectreactor
           reactor-test
           test
       
       
           org.springframework.boot
           spring-boot-starter-test
           test
       
       
       
           org.springframework.cloud
           spring-cloud-starter-loadbalancer
       
       
       
           com.alibaba.cloud
           spring-cloud-starter-alibaba-nacos-discovery
       
   

發動類的代碼省去(qù)了(和前文的一(yī)樣)
裝備信息如下(xià),重點是uri的值lb://provider-hello,用了前綴lb:,後邊的provider-hello就是在nacos注冊的服務名:
server:
  #服務端口
  port: 8085
spring:
  application:
    name: gateway-by-loadbalance
  cloud:
    nacos:
      # 注冊中(zhōng)心的裝備
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: path_route_lb
          uri: lb://provider-hello
          predicates:
          - Path=/lbtest/**

單元測驗類:
package com.bolingcavalry.gateway;

import com.bolingcavalry.common.Constants;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.junit.jupiter.api.Assertions.assertTrue;

@SpringBootTest
@ExtendWith(SpringExtension.class)
@AutoConfigureWebTestClient
public class HelloTest {

    @Autowired
    private WebTestClient webClient;

    @Test
    void testLoadBalance() {
        webClient.get()
                .uri("/lbtest/str")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                // 驗證狀況
                .expectStatus().isOk()
                // 驗證成果,留意成果是字符串格局
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.LB_PREFIX)));
    }

運行單元測驗,經過,可見上述裝備可以經過前綴lb:精确找到服務:


支撐在nacos上裝備
将一(yī)切裝備信息寫在application.yml中(zhōng)有個問題:不能長途裝備,這在應用數量較多的場景就不方便了,好在nacos供給了長途裝備的才能,應用發動後可以從nacos獲得自己的裝備信息,我(wǒ)們來試試
新增名爲gateway-nacos-config的子工(gōng)程,其pom.xml中(zhōng)的依靠情況如下(xià),請留意裏邊的中(zhōng)文注釋,每指明了每一(yī)個依靠的作用:

       
           com.bolingcavalry
           common
           ${project.version}
       
       
           org.springframework.cloud
           spring-cloud-starter-gateway
       
       
           io.projectreactor
           reactor-test
           test
       
       
           org.springframework.boot
           spring-boot-starter-test
           test
       
       
       
           org.springframework.cloud
           spring-cloud-starter-bootstrap
       
       
       
           org.springframework.cloud
           spring-cloud-starter-loadbalancer
       
       
       
           com.alibaba.cloud
           spring-cloud-starter-alibaba-nacos-config
       
       
       
           com.alibaba.cloud
           spring-cloud-starter-alibaba-nacos-discovery
      

本地的裝備文件bootstrap.yml,非常簡略,就是nacos的地址和長途裝備信息:
spring:
  application:
    name: gateway-nacos-config
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yml
        group: DEFAULT_GROUP

 


接下(xià)來再nacos添加一(yī)個裝備文件,操作如下(xià)圖紅框:

添加一(yī)個裝備,要留意的地方如下(xià)(裝備信息的文本稍後給出,便于仿制):

上圖中(zhōng)完整的裝備信息如下(xià):
server:
  port: 8083
spring:
  cloud:
    gateway:
      routes:
        - id: path_route_addr
          uri: http://127.0.0.1:8082
          predicates:
          - Path=/hello/**
        - id: path_route_lb
          uri: lb://provider-hello
          predicates:
          - Path=/lbtest/**

測驗類中(zhōng)的兩個測驗辦法如下(xià)所示,和前面沒有任何區别:
@Test
    void testHelloPredicates() {
        webClient.get()
                .uri("/hello/str")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                // 驗證狀況
                .expectStatus().isOk()
                // 驗證成果,留意成果是字符串格局
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.HELLO_PREFIX)));
    }

    @Test
    void testLoadBalance() {
        webClient.get()
                .uri("/lbtest/str")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                // 驗證狀況
                .expectStatus().isOk()
                // 驗證成果,留意成果是字符串格局
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.LB_PREFIX)));
    }

 


運行單元測驗類,測驗經過,證明從nacos獲取裝備文件成功:

寫代碼的辦法裝備
前面的幾個例子,路由信息都是寫在裝備文件中(zhōng)的,其實還有一(yī)種辦法:寫代碼裝備路由,能自己寫代碼來裝備,這靈敏性就更強了
新增名爲gateway-by-code的子工(gōng)程,其pom.xml文件參照前面工(gōng)程的即可
接下(xià)來的本例的重點,在裝備類中(zhōng)添加一(yī)個RouteLocator類型的bean,經過以下(xià)代碼即可添加一(yī)個路由:
package com.bolingcavalry.gateway.cofig;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RouteConfig {

    @Bean
    public RouteLocator customizeRoute(RouteLocatorBuilder builder) {
        return builder
                .routes()
                .route(
                            // 第一(yī)個參數是路由的唯一(yī)身份
                        "path_route_lb",
                            // 第二個參數是個lambda實現,
                            // 設置了配套條件是依照請求路徑匹配,以及轉發地址,
                            // 留意lb://表示這是個服務名,要從
                            r -> r.path("/lbtest/**").uri("lb://provider-hello")
                )
                .build();
    }
}

 


上述代碼隻裝備了一(yī)個路由,還有一(yī)個在裝備文件中(zhōng),這樣就能驗證代碼和裝備文件能不能同時收效了:
server:
  #服務端口
  port: 8084
spring:
  application:
    name: gateway-by-code
  cloud:
    nacos:
      discovery:
        # nacos服務地址
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: path_route_addr
          uri: http://127.0.0.1:8082
          predicates:
          - Path=/hello/**

 


測驗類和之前工(gōng)程的一(yī)模一(yī)樣,就不占用篇幅了,依舊(jiù)是兩個測驗辦法testHelloPredicates和testLoadBalance
履行單元測驗可以順利經過,證明代碼裝備路由沒有問題:

至此,負載均衡、nacos裝備、代碼裝備的實例我(wǒ)們都測驗過了,它們合起來會給實踐生(shēng)存環境的裝備帶來很大(dà)的方便,期望可以給您一(yī)些參閱
————————————————
版權聲明:本文爲CSDN博主「程序員(yuán)欣宸」的原創文章,遵從CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/boling_cavalry/article/details/119592175本篇概覽
本文是《Spring Cloud Gateway實戰》系列的第二篇,經過前文我(wǒ)們了解到Spring Cloud Gateway的中(zhōng)心是路由裝備,然後在本地application.yml中(zhōng)裝備了一(yī)條路由,但這種修改本地裝備文件的辦法缺少靈敏性,未必能滿意靈敏多變的事務需求,因此,本篇的意圖就是找出本地裝備之外(wài)的其他裝備辦法來,滿意各種實踐需求;
總的來說以下(xià)三種辦法都是常用的:
方針地址支撐用服務名(替代之前的IP+端口);
支撐在nacos上裝備;
支撐寫代碼的辦法裝備;
别的還有一(yī)種愈加靈敏的裝備辦法:動态署理,由于涉及到不少的代碼所以會單獨出一(yī)篇文章詳細介紹
源碼下(xià)載
本篇實戰中(zhōng)的完整源碼可在GitHub下(xià)載到,地址和鏈接信息如下(xià)表所示(https://github.com/zq2599/blog_demos):
名稱 鏈接 備注
項目主頁 https://github.com/zq2599/blog_demos 該項目在GitHub上的主頁
git庫房地址(https) https://github.com/zq2599/blog_demos.git 該項目源碼的庫房地址,https協議
git庫房地址(ssh) git@github.com:zq2599/blog_demos.git 該項目源碼的庫房地址,ssh協議
這個git項目中(zhōng)有多個文件夾,本篇的源碼在spring-cloud-tutorials文件夾下(xià),如下(xià)圖紅框所示:

準備工(gōng)作
正式開(kāi)端前需要再做一(yī)點準備工(gōng)作,整個《Spring Cloud Gateway實戰》系列中(zhōng),一(yī)切請求最後都會被路由到provider-hello這個web上去(qù),該服務現在隻有一(yī)個web接口/hello/str,現在我(wǒ)們再給它添加一(yī)個,後邊的實戰會用到
新添加的web接口來自LBTest.java,可見非常簡略:
package com.bolingcavalry.provider.controller;

import com.bolingcavalry.common.Constants;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.Date;

@RestController
@RequestMapping("/lbtest")
public class LBTest {

    private String dateStr(){
        return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
    }

    /**
     * 回來字符串類型
     * @return
     */
    @GetMapping("/str")
    public String helloStr() {
        return Constants.LB_PREFIX + ", " + dateStr();
    }
}

上述代碼中(zhōng)的Constants.LB_PREFIX來自子工(gōng)程common:
package com.bolingcavalry.common;

public interface Constants {
    String HELLO_PREFIX = "Hello World";
    String LB_PREFIX = "Load balance";
}

寫完代碼後,先保證nacos現已發動
在發動provider-hello工(gōng)程,發動成功後去(qù)看nacos,承認現已注冊:

準備結束,可以開(kāi)端實戰了
方針地址支撐用服務名(替代之前的IP+端口)
我(wǒ)們從最簡略的開(kāi)端,先看前文的路由裝備,如下(xià)圖紅框,方針地址是IP+端口:

玩過Spring Cloud的您天然看出了問題所在:沒有注冊發現,确實,這樣将地址和端口寫死在裝備文件中(zhōng)是不合适的,我(wǒ)們先來處理這個問題;
新增名爲gateway-by-loadbalance的子工(gōng)程,其pom.xml中(zhōng)的依靠情況如下(xià),可見重點是spring-cloud-starter-loadbalancer:

       
           com.bolingcavalry
           common
           ${project.version}
       
       
           org.springframework.cloud
           spring-cloud-starter-gateway
       
       
           io.projectreactor
           reactor-test
           test
       
       
           org.springframework.boot
           spring-boot-starter-test
           test
       
       
       
           org.springframework.cloud
           spring-cloud-starter-loadbalancer
       
       
       
           com.alibaba.cloud
           spring-cloud-starter-alibaba-nacos-discovery
       

發動類的代碼省去(qù)了(和前文的一(yī)樣)
裝備信息如下(xià),重點是uri的值lb://provider-hello,用了前綴lb:,後邊的provider-hello就是在nacos注冊的服務名:
server:
  #服務端口
  port: 8085
spring:
  application:
    name: gateway-by-loadbalance
  cloud:
    nacos:
      # 注冊中(zhōng)心的裝備
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: path_route_lb
          uri: lb://provider-hello
          predicates:
          - Path=/lbtest/**

單元測驗類:
package com.bolingcavalry.gateway;

import com.bolingcavalry.common.Constants;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.junit.jupiter.api.Assertions.assertTrue;

@SpringBootTest
@ExtendWith(SpringExtension.class)
@AutoConfigureWebTestClient
public class HelloTest {

    @Autowired
    private WebTestClient webClient;

    @Test
    void testLoadBalance() {
        webClient.get()
                .uri("/lbtest/str")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                // 驗證狀況
                .expectStatus().isOk()
                // 驗證成果,留意成果是字符串格局
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.LB_PREFIX)));
    }
}

運行單元測驗,經過,可見上述裝備可以經過前綴lb:精确找到服務:

支撐在nacos上裝備
将一(yī)切裝備信息寫在application.yml中(zhōng)有個問題:不能長途裝備,這在應用數量較多的場景就不方便了,好在nacos供給了長途裝備的才能,應用發動後可以從nacos獲得自己的裝備信息,我(wǒ)們來試試
新增名爲gateway-nacos-config的子工(gōng)程,其pom.xml中(zhōng)的依靠情況如下(xià),請留意裏邊的中(zhōng)文注釋,每指明了每一(yī)個依靠的作用:

       
           com.bolingcavalry
           common
           ${project.version}
       
       
           org.springframework.cloud
           spring-cloud-starter-gateway
       
       
           io.projectreactor
           reactor-test
           test
       
       
           org.springframework.boot
           spring-boot-starter-test
           test
       
       
       
           org.springframework.cloud
           spring-cloud-starter-bootstrap
       
       
       
           org.springframework.cloud
           spring-cloud-starter-loadbalancer
       
       
       
           com.alibaba.cloud
           spring-cloud-starter-alibaba-nacos-config
       
       
       
           com.alibaba.cloud
           spring-cloud-starter-alibaba-nacos-discovery
       

本地的裝備文件bootstrap.yml,非常簡略,就是nacos的地址和長途裝備信息:
spring:
  application:
    name: gateway-nacos-config
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        file-extension: yml
        group: DEFAULT_GROUP

接下(xià)來再nacos添加一(yī)個裝備文件,操作如下(xià)圖紅框:

添加一(yī)個裝備,要留意的地方如下(xià)(裝備信息的文本稍後給出,便于仿制):

上圖中(zhōng)完整的裝備信息如下(xià):
server:
  port: 8083
spring:
  cloud:
    gateway:
      routes:
        - id: path_route_addr
          uri: http://127.0.0.1:8082
          predicates:
          - Path=/hello/**
        - id: path_route_lb
          uri: lb://provider-hello
          predicates:
          - Path=/lbtest/**

測驗類中(zhōng)的兩個測驗辦法如下(xià)所示,和前面沒有任何區别:
@Test
    void testHelloPredicates() {
        webClient.get()
                .uri("/hello/str")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                // 驗證狀況
                .expectStatus().isOk()
                // 驗證成果,留意成果是字符串格局
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.HELLO_PREFIX)));
    }

    @Test
    void testLoadBalance() {
        webClient.get()
                .uri("/lbtest/str")
                .accept(MediaType.APPLICATION_JSON)
                .exchange()
                // 驗證狀況
                .expectStatus().isOk()
                // 驗證成果,留意成果是字符串格局
                .expectBody(String.class).consumeWith(result  -> assertTrue(result.getResponseBody().contains(Constants.LB_PREFIX)));
    }

運行單元測驗類,測驗經過,證明從nacos獲取裝備文件成功:

寫代碼的辦法裝備
前面的幾個例子,路由信息都是寫在裝備文件中(zhōng)的,其實還有一(yī)種辦法:寫代碼裝備路由,能自己寫代碼來裝備,這靈敏性就更強了
新增名爲gateway-by-code的子工(gōng)程,其pom.xml文件參照前面工(gōng)程的即可
接下(xià)來的本例的重點,在裝備類中(zhōng)添加一(yī)個RouteLocator類型的bean,經過以下(xià)代碼即可添加一(yī)個路由:
package com.bolingcavalry.gateway.cofig;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RouteConfig {

    @Bean
    public RouteLocator customizeRoute(RouteLocatorBuilder builder) {
        return builder
                .routes()
                .route(
                            // 第一(yī)個參數是路由的唯一(yī)身份
                        "path_route_lb",
                            // 第二個參數是個lambda實現,
                            // 設置了配套條件是依照請求路徑匹配,以及轉發地址,
                            // 留意lb://表示這是個服務名,要從
                            r -> r.path("/lbtest/**").uri("lb://provider-hello")
                )
                .build();
    }
}

上述代碼隻裝備了一(yī)個路由,還有一(yī)個在裝備文件中(zhōng),這樣就能驗證代碼和裝備文件能不能同時收效了:
server:
  #服務端口
  port: 8084
spring:
  application:
    name: gateway-by-code
  cloud:
    nacos:
      discovery:
        # nacos服務地址
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        - id: path_route_addr
          uri: http://127.0.0.1:8082
          predicates:
          - Path=/hello/**

測驗類和之前工(gōng)程的一(yī)模一(yī)樣,就不占用篇幅了,依舊(jiù)是兩個測驗辦法testHelloPredicates和testLoadBalance
履行單元測驗可以順利經過,證明代碼裝備路由沒有問題:

至此,負載均衡、nacos裝備、代碼裝備的實例我(wǒ)們都測驗過了,它們合起來會給實踐生(shēng)存環境的裝備帶來很大(dà)的方便,期望可以給您一(yī)些參閱

 

—— 靈通雲微信公衆号 ——

熱門标簽

上一(yī)條———————

下(xià)一(yī)條———————

十七年 建站經驗

多一(yī)份參考,總有益處

聯系靈通雲,免費(fèi)獲得專屬《策劃方案》及報價

咨詢相關問題或預約面談,可以通過以下(xià)方式與我(wǒ)們聯系

業務熱線:400-688-6062 / 大(dà)客戶專線   南(nán)通:15818561755