SpringCloud之服務網關Gateway

前言

SpringCloud 是微服務中的翹楚,最佳的落地方案。

Spring Cloud Gateway 是 Spring Cloud 新推出的網關框架,之前是 Netflix Zuul。網關通常在項目中為了簡化

前端的調用邏輯,同時也簡化內部服務之間互相調用的複雜度;具體作用就是轉發服務,接收並轉發所有內外

部的客戶端調用;其他常見的功能還有權限認證,限流控制等等。

本博客會提到網關的基本轉發功能,熔斷功能,限流功能以及功能的綜合使用。

環境

JDK 1.8.0 +

Maven 3.0 +

SpringBoot 2.0.3

SpringCloud Finchley.RELEASE

Redis 3.0 +

開發工具

IntelliJ IDEA

正文

commons 工程

commons 工程 - POM 文件

Version:1.0 StartHTML:000000201 EndHTML:000017632 StartFragment:000004537 EndFragment:000017541 StartSelection:000004537 EndSelection:000017534 SourceURL:https://zhuanlan.zhihu.com/p/115763274

<code>

<project>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelversion>4.0.0/<modelversion>





<groupid>com.zwc/<groupid>

<artifactid>springcloud-gateway-commons/<artifactid>

<version>1.0/<version>





<name>springcloud-gateway-commons/<name>

<description>公用工程/<description>





<packaging>jar/<packaging>





<properties>



<project.build.sourceencoding>UTF-8/<project.build.sourceencoding>



<java.version>1.8/<java.version>





<platform-bom.version>Cairo-SR3/<platform-bom.version>





<spring-cloud-dependencies.version>Finchley.RELEASE/<spring-cloud-dependencies.version>

/<properties>





<dependencies>



/<dependencies>











<dependencymanagement>

<dependencies>



<dependency>

<groupid>io.spring.platform/<groupid>

<artifactid>platform-bom/<artifactid>

<version>${platform-bom.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>

/<dependencies>

/<dependencymanagement>





<build>

<plugins>

<plugin>

<groupid>org.springframework.boot/<groupid>

<artifactid>spring-boot-maven-plugin/<artifactid>

/<plugin>

/<plugins>

/<build>

/<project>


/<code>

配置一些共用依賴


SpringCloud之服務網關Gateway

service 工程

① 此工程下有四個模塊:一個註冊中心,一個網關以及兩個提供者

② 兩個提供者除端口不一致以外,其他代碼基本一致

registry-service(註冊中心)

registry-service - POM 文件

<code>

<project>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelversion>4.0.0/<modelversion>





<parent>

<groupid>com.zwc/<groupid>

<artifactid>springcloud-gateway-service/<artifactid>

<version>1.0/<version>

/<parent>





<groupid>com.zwc/<groupid>

<artifactid>springcloud-gateway-registry-service/<artifactid>

<version>1.0/<version>





<name>springcloud-gateway-registry-service/<name>

<description>註冊中心/<description>





<packaging>jar/<packaging>





<properties>



/<properties>





<dependencies>



<dependency>

<groupid>org.springframework.cloud/<groupid>

<artifactid>spring-cloud-starter-netflix-eureka-server/<artifactid>

/<dependency>

/<dependencies>





<build>

<plugins>

<plugin>

<groupid>org.springframework.boot/<groupid>

<artifactid>spring-boot-maven-plugin/<artifactid>

/<plugin>

/<plugins>

/<build>



/<project>
主要主要加入 spring-cloud-starter-netflix-eureka-server 依賴/<code>

registry-service - application.yml 配置文件主要加入 spring-cloud-starter-netflix-eureka-server 依賴

  • 主要加入 spring-cloud-starter-netflix-eureka-server 依賴

registry-service - application.yml 配置文件

<code># 端口

server:


port: 8761



# 應用名稱

spring:

application:

name: eureka-server



eureka:

instance:

# 使用 ip 代替實例名

prefer-ip-address: true

# 實例的主機名

hostname: ${spring.cloud.client.ip-address}

# 實例的 ID 規則

instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

client:

# 是否向註冊中心註冊自己

registerWithEureka: false

# 是否向註冊中心獲取註冊信息

fetchRegistry: false

serviceUrl:

# 註冊中心地址

defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka//<code>
  • 這裡使用了默認的 8761 端口,當然也可以更改,不過在發現調用服務端的註冊中心地址端口要與它一致
  • registry-service - 啟動類

    <code>package com.zwc;



    import org.springframework.boot.SpringApplication;

    import org.springframework.boot.autoconfigure.SpringBootApplication;

    import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;



    @SpringBootApplication

    @EnableEurekaServer

    public class SpringcloudGatewayRegistryServiceApplication {



    public static void main(String[] args) {

    SpringApplication.run(SpringcloudGatewayRegistryServiceApplication.class, args);

    }



    }/<code>
  • 在啟動類中添加 @EnableEurekaServer 註解表示此工程是註冊中心
  • registry-service - 啟動項目

    1. 項目啟動成功後訪問 http://localhost:8761/ 即可看到 eureka-server 主頁面


    SpringCloud之服務網關Gateway

    注:由於服務工程 A 和服務工程 B 除端口不一致以外,其他代碼基本一致,所以服務工程 B 不再贅述

    a-service(服務工程 A)

    a-service - POM 文件

    <code>

    <project>
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelversion>4.0.0/<modelversion>





    <parent>

    <groupid>com.zwc/<groupid>

    <artifactid>springcloud-gateway-a-service/<artifactid>

    <version>1.0/<version>

    /<parent>





    <groupid>com.zwc/<groupid>

    <artifactid>springcloud-gateway-a-service-core/<artifactid>

    <version>1.0/<version>





    <name>springcloud-gateway-a-service-core/<name>

    <description>服務工程 - A 核心/<description>





    <packaging>jar/<packaging>





    <properties>



    /<properties>





    <dependencies>



    <dependency>

    <groupid>com.zwc/<groupid>

    <artifactid>springcloud-gateway-commons/<artifactid>

    <version>1.0/<version>

    /<dependency>






    <dependency>

    <groupid>com.zwc/<groupid>

    <artifactid>springcloud-gateway-a-service-api/<artifactid>

    <version>1.0/<version>

    /<dependency>





    <dependency>

    <groupid>org.springframework.boot/<groupid>

    <artifactid>spring-boot-starter-web/<artifactid>

    /<dependency>





    <dependency>

    <groupid>org.springframework.cloud/<groupid>

    <artifactid>spring-cloud-starter-netflix-eureka-client/<artifactid>

    /<dependency>

    /<dependencies>





    <build>

    <plugins>

    <plugin>

    <groupid>org.springframework.boot/<groupid>

    <artifactid>spring-boot-maven-plugin/<artifactid>

    /<plugin>

    /<plugins>

    /<build>



    /<project>/<code>

    a-service - application.yml 配置文件

    <code># 端口

    server:

    port: 9000



    # 應用名稱

    spring:

    application:

    name: gateway-service



    eureka:

    instance:

    # 使用 ip 代替實例名

    prefer-ip-address: true

    # 實例的主機名


    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka//<code>
  • 注意此處配置註冊中心地址的端口為 8761 也就是上面註冊中心工程配置的端口
  • a-service - controller 前端控制器(提供服務)

    <code>package com.zwc.a.controller;



    import org.springframework.beans.factory.annotation.Value;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RestController;

    /*

    * @Version 1.0

    */

    @RestController

    public class ASayHelloController {

    /*

    * @Desc TODO 讀取配置文件中的端口


    * @Version 1.0

    */

    @Value("${server.port}")

    private String port;

    /*

    */

    @RequestMapping("/hello")

    public String hello(){

    return "Hello!I'm a. port:" + port;

    }



    /*

    * @Desc TODO 接收從網關傳入的參數

    * @Version 1.0

    */

    @RequestMapping("/name")

    public String name(String name){

    return "My name is " + name + ". aaa";

    }



    /*

    * @Desc TODO 接收從網關傳入的參數

    * @Version 1.0

    */


    @RequestMapping("/age")

    public String age(String age){

    return "I am " + age + " years old this year. aaa";

    }



    /*

    * @Desc TODO 接收從網關傳入的參數
    * @Version 1.0

    */

    @RequestMapping("/routeAll")

    public String routeAll(String pass) {

    return "Can I pass? " + pass + "! port:" + port;

    }



    }
    /<code>
    • 提供輸出字符串服務,供網關調用

    a-service - 啟動類

    <code>package com.zwc;



    import org.springframework.boot.SpringApplication;

    import org.springframework.boot.autoconfigure.SpringBootApplication;

    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;



    @SpringBootApplication

    @EnableEurekaClient

    public class SpringcloudGatewayAServiceCoreApplication {



    public static void main(String[] args) {

    SpringApplication.run(SpringcloudGatewayAServiceCoreApplication.class, args);

    }



    }
    /<code>
    • 添加 @EnableEurekaClient 註解表示此工程可以向註冊中心提供服務

    a-service - 啟動項目

    1. 刷新 http://localhost:8761/(註冊中心)可以看到服務已經被註冊進來了


    SpringCloud之服務網關Gateway

    2. 項目啟動成功後訪問:http://localhost:9000/hello

    3. 輸出內容:'Hello!I'm a. port:9000'

    4. 同樣啟動服務工程 B後,刷新 http://localhost:8761/(註冊中心)


    SpringCloud之服務網關Gateway

    5. 項目啟動成功後訪問:http://localhost:9001/hello

    6. 輸出內容:'Hello!I'm b. port:9001'

    7. 其他接口是下面網關服務啟動後轉發調用的,也是本博客的重頭戲

    master-service(網關)

    master-service - POM 文件

    <code>

    <project>
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelversion>4.0.0/<modelversion>





    <parent>

    <groupid>com.zwc/<groupid>

    <artifactid>springcloud-gateway-service/<artifactid>

    <version>1.0/<version>

    /<parent>





    <groupid>com.zwc/<groupid>

    <artifactid>springcloud-gateway-master-service/<artifactid>

    <version>1.0/<version>





    <name>springcloud-gateway-master-service/<name>

    <description>Spring Cloud Gateway 服務網關/<description>





    <packaging>jar/<packaging>





    <properties>



    <fastjson.version>1.2.47/<fastjson.version>

    /<properties>





    <dependencies>



    <dependency>

    <groupid>org.springframework.cloud/<groupid>

    <artifactid>spring-cloud-starter-netflix-eureka-client/<artifactid>

    /<dependency>





    <dependency>

    <groupid>org.springframework.cloud/<groupid>

    <artifactid>spring-cloud-starter-gateway/<artifactid>

    /<dependency>





    <dependency>

    <groupid>org.springframework.boot/<groupid>

    <artifactid>spring-boot-starter-data-redis-reactive/<artifactid>

    /<dependency>





    <dependency>

    <groupid>org.springframework.cloud/<groupid>

    <artifactid>spring-cloud-starter-netflix-hystrix/<artifactid>

    /<dependency>





    <dependency>

    <groupid>com.alibaba/<groupid>

    <artifactid>fastjson/<artifactid>

    <version>${fastjson.version}/<version>

    /<dependency>

    /<dependencies>





    <build>

    <plugins>

    <plugin>

    <groupid>org.springframework.boot/<groupid>

    <artifactid>spring-boot-maven-plugin/<artifactid>

    /<plugin>

    /<plugins>

    /<build>

    /<project>
    /<code>

    加入 spring-cloud-starter-netflix-eureka-client 依賴:提供和註冊服務

    加入 spring-cloud-starter-gateway 依賴:gateway

    加入 spring-boot-starter-data-redis-reactive 依賴:結合 Redis 限流

    加入 spring-cloud-starter-netflix-hystrix 依賴:熔斷器

    master-service - application.yml 配置文件

    <code># 端口

    server:

    port: 8000



    spring:

    profiles:


    # 指定配置

    # route_simple:簡單嘗試

    # route_stripPrefix:截取請求

    # route_uri:轉發指定地址並傳入參數

    # route_addRequestParameter:轉發指定服務並傳入參數

    # route_hystrix:熔斷

    # route_requestRateLimiter:限流

    # route_all:綜合

    active: route_simple



    ---



    spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 簡單嘗試

    profiles: route_simple

    application:

    # 應用名稱

    name: gateway-master

    cloud:

    gateway:


    discovery:

    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:

    # 路由標識(id:標識,具有唯一性) 簡單嘗試

    - id: route_simple

    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: https://www.zouwencong.com

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)

    predicates:

    ## 轉發地址格式為 uri/archive

    - Path=/archive



    eureka:

    instance:

    # 使用 ip 代替實例名


    prefer-ip-address: true

    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka/



    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug



    ---



    spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 截取請求

    profiles: route_stripPrefix

    application:

    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:

    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:

    # 路由標識(id:標識,具有唯一性) 截取請求

    - id: route_simple

    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: https://www.zouwencong.com

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)

    predicates:

    ## 轉發地址格式為 uri/archive,/str 部分會被下面的過濾器給截取掉

    - Path=/str/archive

    filters:

    ## 截取路徑位數

    - StripPrefix=1



    eureka:

    instance:

    # 使用 ip 代替實例名

    prefer-ip-address: true

    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka/



    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug



    ---




    spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 轉發指定地址並傳入參數

    profiles: route_uri

    application:

    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:

    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:

    # 路由標識(id:標識,具有唯一性) 轉發指定地址並傳入參數

    - id: route_uri

    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: http://localhost:9000

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)

    predicates:

    ## 匹配 GET 請求

    - Method=GET

    # 過濾器(filters:過濾器,過濾規則)

    filters:

    ## 添加指定參數

    - AddRequestParameter=name, zwc



    eureka:

    instance:

    # 使用 ip 代替實例名

    prefer-ip-address: true

    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:


    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka/



    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug



    ---



    spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 轉發指定服務並傳入參數

    profiles: route_addRequestParameter

    application:

    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:

    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務


    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:

    # 路由標識(id:標識,具有唯一性) 轉發指定服務並傳入參數

    - id: route_addRequestParameter

    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: lb://gateway-service

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)

    predicates:

    ## 匹配 GET 請求

    - Method=GET

    # 過濾器(filters:過濾器,過濾規則)

    filters:

    ## 添加指定參數

    - AddRequestParameter=age, three



    eureka:

    instance:

    # 使用 ip 代替實例名

    prefer-ip-address: true

    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka/



    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug



    ---



    spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 熔斷

    profiles: route_hystrix

    application:

    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:

    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:

    # 路由標識(id:標識,具有唯一性) 熔斷

    - id: route_hystrix

    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: lb://gateway-service

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)

    predicates:

    ## 匹配 GET 請求

    - Method=GET

    # 過濾器(filters:過濾器,過濾規則)

    filters:

    ## 添加指定參數

    - AddRequestParameter=age, three

    ## 熔斷

    - name: Hystrix

    args:

    name: fallbackcmd

    ### fallback 時調用的方法 http://localhost:8000/fallback

    fallbackUri: forward:/fallback



    eureka:

    instance:

    # 使用 ip 代替實例名

    prefer-ip-address: true

    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址


    defaultZone: http://${eureka.instance.hostname}:8761/eureka/



    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug



    ---



    spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 限流

    profiles: route_requestRateLimiter

    redis:

    host: localhost

    port: 6379

    database: 0

    application:

    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:


    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:

    # 路由標識(id:標識,具有唯一性) 限流

    - id: route_requestRateLimiter

    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: lb://gateway-service

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)

    predicates:

    ## 匹配 GET 請求

    - Method=GET

    # 過濾器(filters:過濾器,過濾規則)

    filters:

    ## 添加指定參數

    - AddRequestParameter=age, three


    ## 限流

    - name: RequestRateLimiter

    args:

    ### 限流過濾器的 Bean 名稱

    key-resolver: '#{@uriKeyResolver}'

    ### 希望允許用戶每秒處理多少個請求

    redis-rate-limiter.replenishRate: 1

    ### 用戶允許在一秒鐘內完成的最大請求數

    redis-rate-limiter.burstCapacity: 3



    eureka:

    instance:

    # 使用 ip 代替實例名

    prefer-ip-address: true

    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka/




    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug



    ---



    spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 綜合

    profiles: route_all

    redis:

    host: localhost

    port: 6379

    database: 0

    application:

    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:

    locator:


    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:

    # 路由標識(id:標識,具有唯一性) 綜合

    - id: route_all

    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: lb://gateway-service

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)

    predicates:

    ## 轉發地址格式為 uri/routeAll,/all 部分會被下面的過濾器給截取掉

    - Path=/all/routeAll

    ## 匹配 GET 請求

    - Method=GET

    # 過濾器(filters:過濾器,過濾規則)

    filters:

    ## 截取路徑位數

    - StripPrefix=1

    ## 添加指定參數

    - AddRequestParameter=pass, yes

    ## 熔斷

    - name: Hystrix

    args:

    name: fallbackcmd

    ### fallback 時調用的方法 http://localhost:8000/fallback

    fallbackUri: forward:/fallback

    ## 限流

    - name: RequestRateLimiter

    args:

    ### 限流過濾器的 Bean 名稱

    key-resolver: '#{@uriKeyResolver}'

    ### 希望允許用戶每秒處理多少個請求

    redis-rate-limiter.replenishRate: 1

    ### 用戶允許在一秒鐘內完成的最大請求數

    redis-rate-limiter.burstCapacity: 3



    eureka:

    instance:

    # 使用 ip 代替實例名

    prefer-ip-address: true

    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka/



    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug/<code>

    注意配置註冊中心地址的端口都為 8761 也就是上面註冊中心工程配置的端口

    每一對 '---' 符號中的配置文件都是單獨的,使用 spring.profiles.active 指定

    每一對 '---' 符號中的配置文件都只配置了一個 route(路由)

    route(路由)由四部分組成,其中 filters 不是必須參數

    唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)

    master-service - 簡單嘗試

    <code>spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 簡單嘗試

    profiles: route_simple

    application:

    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:

    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:

    # 路由標識(id:標識,具有唯一性) 簡單嘗試

    - id: route_simple


    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: https://www.zouwencong.com

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)

    predicates:

    ## 轉發地址格式為 uri/archive

    - Path=/archive/<code>

    1. 停止註冊中心工程(registry-service)、服務工程 A 和服務工程 B

    2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_simple

    3. 上面配置文件內容意思是當訪問 http://localhost:8000/archive (網關地址/archive)

    會被轉發到 https://www.zouwencong.com/archive/ (uri/archive)

    4. 啟動註冊中心工程(registry-service)和網關工程(master-service)

    5. 項目啟動成功後訪問:http://localhost:8000/archive

    6. 發現頁面會自動被跳轉到:https://www.zouwencong.com/archive/

    7. 證明服務轉發成功

    master-service - 截取請求

    <code>spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。


    ## 截取請求

    profiles: route_stripPrefix

    application:

    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:

    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:

    # 路由標識(id:標識,具有唯一性) 截取請求

    - id: route_simple

    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: https://www.zouwencong.com

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)


    predicates:

    ## 轉發地址格式為 uri/archive,/str 部分會被下面的過濾器給截取掉

    - Path=/str/archive

    filters:

    ## 截取路徑位數

    - StripPrefix=1



    eureka:

    instance:

    # 使用 ip 代替實例名

    prefer-ip-address: true

    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka/



    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug/<code>

    org.springframework.cloud.gateway: debug

    1. 停止註冊中心工程(registry-service)和網關工程(master-service)

    2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_stripPrefix

    3. 上面配置文件內容意思是訪問的路徑 http://localhost:8000/str/archive (網關地址/str/archive)截取 /str 部分,

    截取後被轉發到 https://www.zouwencong.com/archive/ (uri/archive)

    4. 啟動註冊中心工程(registry-service)和網關工程(master-service)

    5. 項目啟動成功後訪問:http://localhost:8000/str/archive

    6. 發現頁面會自動被跳轉到:https://www.zouwencong.com/archive/

    7. 證明路徑被截取並服務轉發成功

    master-service - 轉發指定地址並傳入參數

    <code>spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 轉發指定地址並傳入參數

    profiles: route_uri

    application:


    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:

    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:

    # 路由標識(id:標識,具有唯一性) 轉發指定地址並傳入參數

    - id: route_uri

    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: http://localhost:9000

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)

    predicates:

    ## 匹配 GET 請求

    - Method=GET

    # 過濾器(filters:過濾器,過濾規則)

    filters:

    ## 添加指定參數

    - AddRequestParameter=name, zwc



    eureka:

    instance:

    # 使用 ip 代替實例名

    prefer-ip-address: true
    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka/



    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug/<code>

    1. 停止註冊中心工程(registry-service)和網關工程(master-service)

    2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_uri

    3. 上面配置文件內容意思是訪問的路徑 http://localhost:8000/name (網關地址/name)

    會被轉發到 http://localhost:9000/name(uri/name),並傳入 'name=zwc' 參數(注意為 Get 請求)

    4. 啟動註冊中心工程(registry-service),網關工程(master-service)和服務工程 A(a-service)

    5. 項目啟動成功後訪問:http://localhost:8000/name

    6. 輸出內容:'My name is zwc. aaa'(通過網關轉發 - 參數有值)

    7. 打開新頁面訪問:http://localhost:9000/name

    8. 輸出內容:'My name is null. aaa'(直接訪問 - 參數沒有值)

    9. 證明轉發指定地址並傳入參數成功

    master-service - 轉發指定服務並傳入參數

    <code>spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 轉發指定服務並傳入參數

    profiles: route_addRequestParameter

    application:


    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:

    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:
    # 路由標識(id:標識,具有唯一性) 轉發指定服務並傳入參數

    - id: route_addRequestParameter

    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: lb://gateway-service

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)

    predicates:

    ## 匹配 GET 請求

    - Method=GET


    # 過濾器(filters:過濾器,過濾規則)

    filters:

    ## 添加指定參數

    - AddRequestParameter=age, three



    eureka:

    instance:

    # 使用 ip 代替實例名

    prefer-ip-address: true

    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka/



    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug/<code>

    1. 停止註冊中心工程(registry-service),網關工程(master-service)和服務工程 A(a-service)

    2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值

    更改為 route_addRequestParameter

    3. 上面配置文件內容意思是訪問的路徑 http://localhost:8000/age (網關地址/age)

    會被轉發到 http://gateway-service/age(uri/age),並傳入 'age=three' 參數(注意為 Get 請求)

    4. 注意此處的配置 uri: lb://gateway-service 與之前都有所不同,之前都是指定了明確的轉發地址,可以滿足

    單個服務轉發的需求,但是一般情況都會有多個服務,所以這裡是指定的服務名稱,格式為:lb://應用註冊

    服務名。

    5. 啟動註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)

    6. 項目啟動成功後訪問:http://localhost:8000/age

    7. 這時可能會報錯 500.錯誤信息為 'Unable to find instance for gateway-service'

    8. 這種情況不要慌張,只是服務還沒有被註冊到註冊中心,稍等片刻再訪問

    9. 多次訪問:http://localhost:8000/age

    10. 輪流輸出內容:'I am three years old this year. aaa' 和 'I am three years old this year. bbb'

    11. 此時還通過網關達到了負載均衡的效果

    12. 證明轉發指定服務並傳入參數成功

    master-service - 熔斷

    <code>spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 熔斷

    profiles: route_hystrix

    application:

    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:

    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:


    # 路由標識(id:標識,具有唯一性) 熔斷

    - id: route_hystrix

    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: lb://gateway-service

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)

    predicates:

    ## 匹配 GET 請求

    - Method=GET

    # 過濾器(filters:過濾器,過濾規則)

    filters:

    ## 添加指定參數

    - AddRequestParameter=age, three

    ## 熔斷

    - name: Hystrix

    args:

    name: fallbackcmd

    ### fallback 時調用的方法 http://localhost:8000/fallback

    fallbackUri: forward:/fallback



    eureka:

    instance:


    # 使用 ip 代替實例名

    prefer-ip-address: true

    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka/



    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug/<code>

    1. 停止註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)

    2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_hystrix

    3. 上面配置文件內容意思是訪問的路徑 http://localhost:8000/age (網關地址/age)

    會被轉發到 http://gateway-service/age(uri/age),並傳入 'age=three' 參數(注意為 Get 請求)

    4. 注意此處的配置 uri: lb://gateway-service 與之前都有所不同,之前都是指定了明確的轉發地址,可以滿足

    單個服務轉發的需求,但是一般情況都會有多個服務,所以這裡是指定的服務名稱,格式為:lb://應用註冊

    服務名。

    5. 此處還多配置了一個過濾器 '- name: Hystrix'(熔斷)

    6. 當請求服務出錯時,會調用 fallback,路徑為:http://localhost:8000/fallback (網關地址/fallback)

    7. 此時就需要如下前端控制器

    master-service - 熔斷 - controller

    <code>package com.zwc.gateway.hystrix;



    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RestController;



    /**


    * @Desc TODO 網關斷路器


    * @Version 1.0

    */

    @RestController

    public class FallbackController {



    /*


    * @Desc TODO 網關斷路器


    * @Version 1.0

    */

    @RequestMapping("/fallback")

    public String fallback() {

    return "I'm Spring Cloud Gateway fallback.";

    }



    }
    /<code>

    8. 啟動註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)

    9. 項目啟動成功後訪問:http://localhost:8000/age

    10. 輸出內容:'I'm Spring Cloud Gateway fallback.'

    11. 證明熔斷成功

    master-service - 限流(重點,解決不生效問題)

    <code>spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 限流

    profiles: route_requestRateLimiter

    redis:

    host: localhost

    port: 6379

    database: 0

    application:

    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:

    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:

    # 路由標識(id:標識,具有唯一性) 限流

    - id: route_requestRateLimiter

    # 目標服務地址(uri:地址,請求轉發後的地址)

    uri: lb://gateway-service

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)


    predicates:

    ## 匹配 GET 請求

    - Method=GET

    # 過濾器(filters:過濾器,過濾規則)

    filters:

    ## 添加指定參數

    - AddRequestParameter=age, three

    ## 限流

    - name: RequestRateLimiter

    args:

    ### 限流過濾器的 Bean 名稱

    key-resolver: '#{@uriKeyResolver}'

    ### 希望允許用戶每秒處理多少個請求

    redis-rate-limiter.replenishRate: 1

    ### 用戶允許在一秒鐘內完成的最大請求數

    redis-rate-limiter.burstCapacity: 3



    eureka:

    instance:

    # 使用 ip 代替實例名

    prefer-ip-address: true

    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka/



    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug
    /<code>

    1. 停止註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)

    2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值

    更改為 route_requestRateLimiter

    3. 上面配置文件內容意思是訪問的路徑 http://localhost:8000/age (網關地址/age)

    會被轉發到 http://gateway-service/age(uri/age),並傳入 'age=three' 參數(注意為 Get 請求)

    4. 注意此處還需要配置 redis 的連接信息

    5. 注意此處是結合 redis 實現的限流,所以 filter 過濾器的 name 必須為 RequestRateLimiter

    6. 並且通過實現 KeyResolver 類來自定義限流策略,如下

    master-service - 限流 - 策略

    <code>package com.zwc.gateway.config.filters;



    import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;

    import org.springframework.web.server.ServerWebExchange;

    import reactor.core.publisher.Mono;



    /**

    * @Desc TODO Spring Cloud Gateway 網關限流過濾器

    * @Version 1.0

    */

    public class UriKeyResolver implements KeyResolver {



    /*

    * @Desc TODO 根據請求的 uri 限流

    * @Version 1.0

    */

    @Override

    public Mono<string> resolve(ServerWebExchange exchange) {

    return Mono.just(exchange.getRequest().getURI().getPath());

    }




    }
    /<string>/<code>

    7. 啟動本地 redis(redis-server.exe) 服務

    8. 啟動註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)

    9. 項目啟動成功後訪問:http://localhost:8000/age

    10. 此時限流卻無論如何都不生效,原因有如下兩點

    ① redis-server 版本過低!我 Windows 本地是 redis-2.4.2 版本的,要用 3 以上的版本!!!

    ② 數據在 redis 中存儲的時間只有幾秒,所以得使用 monitor 指令來動態的觀察!!!

    11. 打開 redis-cli.exe,輸入命令 monitor

    12. 快速刷新地址:http://localhost:8000/age

    13. 頁面上會出現 429,redis-cli.exe 中會出現很多數據交互(http://request_rate_limiter.xxx 開頭的 key)

    14. 證明限流成功

    master-service - 綜合

    <code>spring:

    # 配置文件名稱,用來標識不同環境的配置。由 spring.profiles.active 的值來決定使用哪組配置。

    ## 綜合

    profiles: route_all

    redis:

    host: localhost

    port: 6379

    database: 0

    application:

    # 應用名稱

    name: gateway-master

    cloud:

    gateway:

    discovery:

    locator:

    # 是否和服務註冊與發現組件結合,設置為 true 後可以直接使用應用名稱調用服務

    enabled: true

    # 路由(routes:路由,它由唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)。filters 不是必需參數。)

    routes:

    # 路由標識(id:標識,具有唯一性) 綜合

    - id: route_all

    # 目標服務地址(uri:地址,請求轉發後的地址)


    uri: lb://gateway-service

    # 路由條件(predicates:斷言,匹配 HTTP 請求內容)

    predicates:

    ## 轉發地址格式為 uri/routeAll,/all 部分會被下面的過濾器給截取掉

    - Path=/all/routeAll

    ## 匹配 GET 請求

    - Method=GET

    # 過濾器(filters:過濾器,過濾規則)

    filters:

    ## 截取路徑位數

    - StripPrefix=1

    ## 添加指定參數

    - AddRequestParameter=pass, yes

    ## 熔斷

    - name: Hystrix

    args:

    name: fallbackcmd

    ### fallback 時調用的方法 http://localhost:8000/fallback

    fallbackUri: forward:/fallback

    ## 限流

    - name: RequestRateLimiter

    args:

    ### 限流過濾器的 Bean 名稱

    key-resolver: '#{@uriKeyResolver}'

    ### 希望允許用戶每秒處理多少個請求

    redis-rate-limiter.replenishRate: 1

    ### 用戶允許在一秒鐘內完成的最大請求數

    redis-rate-limiter.burstCapacity: 3



    eureka:

    instance:

    # 使用 ip 代替實例名

    prefer-ip-address: true

    # 實例的主機名

    hostname: ${spring.cloud.client.ip-address}

    # 實例的 ID 規則

    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}

    client:

    serviceUrl:

    # 註冊中心地址

    defaultZone: http://${eureka.instance.hostname}:8761/eureka/



    logging:

    level:

    # log 級別

    org.springframework.cloud.gateway: debug
    /<code>

    1. 停止註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)

    2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_all

    3. 上面配置文件內容意思是訪問的路徑 http://localhost:8000/all/routeAll (網關地址/all/routeAll)截取 /all 部分,

    會被轉發到 http://gateway-service/routeAll(uri/routeAll),並傳入 'pass=yes' 參數(注意為 Get 請求)

    4. 啟動註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)

    5. 項目啟動成功後訪問:http://localhost:8000/all/routeAll

    6. 首先會返回 'I'm Spring Cloud Gateway fallback.',因為服務還未被註冊到註冊中心

    7. 然後會返回 '{"msg":"缺少憑證","code":-1}',因為配置了全局過濾器,如下

    <code>package com.zwc.gateway.config.filters;



    import com.alibaba.fastjson.JSONObject;

    import org.springframework.cloud.gateway.filter.GatewayFilterChain;

    import org.springframework.cloud.gateway.filter.GlobalFilter;

    import org.springframework.core.Ordered;


    import org.springframework.http.HttpStatus;

    import org.springframework.http.server.reactive.ServerHttpRequest;

    import org.springframework.http.server.reactive.ServerHttpResponse;

    import org.springframework.web.server.ServerWebExchange;

    import reactor.core.publisher.Mono;

    import org.springframework.core.io.buffer.DataBuffer;



    import java.net.InetSocketAddress;

    import java.nio.charset.StandardCharsets;



    /**

    * @Desc TODO 請求認證過濾器

    * @Version 1.0

    */

    public class TokenFilter implements GlobalFilter{



    @Override

    public Mono<void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

    // 請求對象

    ServerHttpRequest request = exchange.getRequest();

    // 響應對象

    ServerHttpResponse response = exchange.getResponse();



    // 只有綜合路由才添加這個全局過濾器(routesId:route_all)


    // 如果請求路徑中不存在 routeAll 字符串

    if(request.getURI().toString().indexOf("routeAll") == -1){

    System.out.println("filter -> return");

    // 直接跳出

    return chain.filter(exchange);

    }



    // 從請求中獲取 token 參數

    String token = exchange.getRequest().getQueryParams().getFirst("token");

    // 如果為空,那麼將返回 401

    if (token == null || token.isEmpty()) {



    // 響應消息內容對象

    JSONObject message = new JSONObject();

    // 響應狀態

    message.put("code", -1);

    // 響應內容

    message.put("msg", "缺少憑證");

    // 轉換響應消息內容對象為字節

    byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);

    DataBuffer buffer = response.bufferFactory().wrap(bits);

    // 設置響應對象狀態碼 401


    response.setStatusCode(HttpStatus.UNAUTHORIZED);

    // 設置響應對象內容並且指定編碼,否則在瀏覽器中會中文亂碼

    response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");

    // 返回響應對象

    return response.writeWith(Mono.just(buffer));

    }

    // 獲取請求地址

    String beforePath = request.getPath().pathWithinApplication().value();

    // 獲取響應狀態碼

    HttpStatus beforeStatusCode = response.getStatusCode();

    System.out.println("響應碼:" + beforeStatusCode + ",請求路徑:" + beforePath);

    // 請求前

    System.out.println("filter -> before");

    // 如果不為空,就通過

    return chain.filter(exchange).then(Mono.fromRunnable(() -> {

    // 獲取請求地址

    String afterPath = request.getPath().pathWithinApplication().value();

    // 獲取響應狀態碼

    HttpStatus afterStatusCode = response.getStatusCode();

    System.out.println("響應碼:" + afterStatusCode + ",請求路徑:" + afterPath);

    // 響應後

    System.out.println("filter -> after");

    }));

    }



    }
    /<void>/<code>

    8. 全局過濾器,不需要配置在配置文件中,作用於所有路由;只是這裡在處理前做了判斷,只有路徑中存在

    routeAll 字符串才到後續處理;並且處理分為請求前的處理,和響應後的處理

    9. 此時在地址:http://localhost:8000/all/routeAll 中添加 token 參數

    10. 訪問:http://localhost:8000/all/routeAll?token=123

    11. 輪流輸出內容:'Can I pass? yes! port:9000' 和 'Can I pass? yes! port:9001'

    12. 觀察 gateway 工程的控制檯,會有如下內容輸出

    <code>響應碼:null,請求路徑:/routeAll

    filter -> before

    響應碼:200,請求路徑:/routeAll

    filter -> after
    /<code>

    13. 證明全局過濾器過濾成功


    SpringCloud之服務網關Gateway

    把多工程項目使用 IntelliJ IDEA 打開

    把項目從 GitHub 中下載到你的本地

    1. 打開 IntelliJ IDEA
    2. 點擊 File -> Open
    3. 打開你下載到本地的項目目錄
    4. springcloud-gateway -> springcloud-gateway-service(選擇打開此工程)
    5. 打開 service 工程後
    6. 再次點擊 File -> Project Structrue
    7. 選擇 Modules,點擊 '+' 符號
    8. 點擊 Import Module
    9. 還是打開你下載到本地的項目目錄
    10. springcloud-gateway -> springcloud-gateway-commons -> pom.xml
    11. 點擊 OK
    12. 點擊 Next,Finish
    13. 點擊 Apply,OK

    希望對大家有幫助

    JAVA進階架構程序員福利:我這裡還總結整理了比較全面的JAVA相關的面試資料,都已經整理成了

    PDF版,這些都可以分享給大家,關注私信我:【806】,免費領取!


    分享到:


    相關文章: