Gateway網關入門指南


Spring Cloud Gateway

粗話網關

網關,是整個微服務平台所有請求的統一入口,所有客戶端和服務端之間的聯系都通過網關來接入,相當於就是一個不賺差價的中間商,Spring Cloud Gateway做為替換上一代網關產品Zuul的新組件出現在Spring Cloud 2.0以及之后的版本中,網關作為一個服務的唯一入口,其中可以集成我們項目中除了業務之外的很多功能,比如認證授權,路由、負載均衡、日志、過濾等等一些列功能,

想了解Gateway就得我們就先了解它的三大功能名詞

  • 斷言

    • 匹配http中請求頭或者請求參數,如果請求與斷言想匹配則進行路由

  • 路由

    • 根據斷言規則,將某些請求轉發到指定的服務器上

  • 過濾器

    • 過濾可以發生在路由前后,使用過濾器的思想,對請求進行修改或者監視

10分鍾寫個Demo

演示Demo大致如下,創建一個訂單模塊,一個支付模塊(端口不同的兩個應用),一個網關模塊

演示功能如下:

  • Gateway + Nacos + Openfein,簡單跑通一下,主要關注點在於Gateway的基本使用和學習上

父工程pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         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>org.example</groupId>
    <artifactId>springcloud_alibaba</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
   
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-project-info-reports-plugin</artifactId>
                <version>3.0.0</version>
            </dependency>
            <!--spring boot 2.2.2-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.2.2.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency><!--spring cloud Alibaba-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>2.1.0.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency><!--spring cloud Hoxton.SR1-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement><build>
    <pluginManagement>
        <plugins>
            <plugin>
                <artifactId>maven-clean-plugin</artifactId>
                <version>3.1.0</version>
            </plugin>
            <plugin>
                <artifactId>maven-site-plugin</artifactId>
                <version>3.7.1</version>
            </plugin>
            <plugin>
                <artifactId>maven-project-info-reports-plugin</artifactId>
                <version>3.0.0</version>
            </plugin>
        </plugins>
    </pluginManagement><plugins>
            <!--熱部署配置-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin><plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

支付工程子模塊(兩個)

創建完后,復制一個出來,就該一下端口,使端口不同即可

該模塊用於后面演示:

  • 訂單模塊負載均衡調用支付模塊

  • 網關模塊負載均衡調用支付模塊

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud_alibaba</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion><artifactId>payment_8801</artifactId><dependencies>
        <!-- nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- SpringCloud ailibaba sentinel-datasource-nacos 持久化需要用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!-- SpringCloud ailibaba sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--監控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--監控 以json格式輸出信息-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-hateoas</artifactId>
        </dependency>
    </dependencies>
</project>
  • application.yml

server:
  port: 8801
spring:
  application:
    name: payment-server
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        #配置地址
        dashboard: localhost:8080
        #默認8719端口,本地啟動 HTTP API Server 的端口號
        port: 8719#監控
management:
  endpoints:
    web:
      exposure:
        include: '*'
  • Controller

@RestController
@RequestMapping("/payment")
public class PaymentController {
​
    @Value("${server.port}")
    private String port;
​
    @GetMapping("/test1/{id}")
    public String test1(@PathVariable("id") Integer id){
        return "This is Payment server,Port is " + port + "\t id為" + id;
     }
}
  • 啟動類

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableDiscoveryClient
public class PaymentApplication8801 {
    public static void main(String[] args) {
        SpringApplication.run(PaymentApplication8801.class);
    }
}

訂單工程子模塊

該模塊的作用:

  • Gatwway學習中調用該模塊進行演示

  • 該模塊負載均衡調用支付模塊,跑個流程

  • pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud_alibaba</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion><artifactId>order_8803</artifactId><dependencies>
        <!-- nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- SpringCloud ailibaba sentinel-datasource-nacos 持久化需要用到-->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
        </dependency>
        <!-- SpringCloud ailibaba sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--遠程調用 OpenFeign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--監控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--監控 以json格式輸出信息-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-hateoas</artifactId>
        </dependency>
    </dependencies>
</project>

application.yml

server:
  port: 8803
spring:
  application:
    name: order-server
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    sentinel:
      transport:
        #配置地址
        dashboard: localhost:8080
        #默認8719端口,本地啟動 HTTP API Server 的端口號
        port: 8719
      #持久化規則到Nacos中,Nacos又通過配置持久化到數據mysql中
      datasource:
        ds1:
          nacos:
            server-addr: localhost:8848 #nacos地址
            dataId: order-server-sentinel  #微服務名稱
            groupId: DEFAULT_GROUP  #默認分組
            data-type: json #數據格式
            rule-type: flow #流控規則
#feign集成hystrix需要配置開啟,實現降級
feign:
  sentinel:
    enabled: true
#監控
management:
  endpoints:
    web:
      exposure:
        include: '*'
  • 遠程調用Client

@FeignClient(value = "payment-server",fallback = PaymentClientDuty.class)
public interface PaymentClient {
​
    @GetMapping("/payment/test1/{id}")
    public String test1(@PathVariable("id") Integer id);
}
@Component
public class PaymentClientDuty implements PaymentClient {
​
    @Override
    public String test1(Integer id) {
        return "OpenFeign遠程調用失敗調用" + id;
    }
}
  • controller

@RestController
public class OrderController {
​
    @Autowired
    private PaymentClient paymentClient;
    
    @GetMapping("/order/{id}")
    public String openfeignTest(@PathVariable("id") Integer id){
        return paymentClient.test1(id);
    }
}
  • 啟動類

@EnableDiscoveryClient
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableFeignClients(basePackages = "com.nacos.order.clients")
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class);
    }

網關工程子模塊

  • pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud_alibaba</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion><artifactId>gateway_8800</artifactId>
    <packaging>jar</packaging><dependencies>
        <!-- nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- SpringCloud ailibaba sentinel-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies><build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build></project>
  • application.yml

server:
  port: 8800
​
spring:
  application:
    name: gateway-server
​
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848   #作為注冊中心的地址
    gateway:
      routes:
        - id: test1
          uri: http://localhost:8803
          predicates:
            - Path=/order/**
  • 啟動類

package com.ninja.gateway;
​
import org.bouncycastle.math.ec.endo.GLVTypeAEndomorphism;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
​
/**
 * @Description
 * @Author Ninja
 * @Date 2020/8/30
 **/
​
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class);
    }
}

配置文件詳細說明

在我們的網關工程子模塊中,可以看到下面的一配置

網關的路由配置,可以采用硬編碼的方式也可以采用如下配置文件的方式

  • 當然硬編碼的方式因為是寫死在代碼中,擴展性和動態性就受到了限制,不做過多說明

  • 我們就對配置文件的方式做一個詳細的解說

gateway:
  routes:
    - id: test1
      uri: http://localhost:8803
      predicates:
        - Path=/order/**

上面只是一段配置,全稱應該為speing.cloud.gateway.routes

  • routes:路由的復數形式,用來包含所有的路由規則等相關信息

    • id: 路由id,隨便取,唯一要求就是全局唯一,一般我們配合服務名進行配置

    • uri:路由地址,這就是斷言后的請求轉發地址,

      • 一般不會使用具體的ip和端口,而是配合nacos注冊中心一起使用

      • 具體下面詳細講解

    • predicates:斷言的復數,表示包含所有的斷言規則

      • path : 就是一個斷言中的一種

上面的路由配置文件中,主要實現的功能為:

  • 網關的端口8800,

  • 當我們訪問localhost:8800/order/xx時,請求會轉發到localhost:8803/order/xx

可見路由轉發已經生效

斷言類型詳解

path

上面我們使用path 意思就是,路徑相匹配則進行路由跳轉,還有很多的規則可以配置,下面慢慢道來

After

  • After:可以指定,只有在指定時間后,才可以路由到指定微服務

ZonedDateTime date = ZonedDateTime.now();
System.out.println(date); //獲得時間,寫個測試得到即可

現在我們將配置文件修改為如下

gateway:
  routes:
    - id: test1
      uri: lb://payment-server
      predicates:
        - Path=/payment/test1/**
        - After=2020-08-30T14:37:20.465+08:00[Asia/Shanghai]
  • uri 修改為指定注冊中心上的服務,而不是固定的ip和端口

  • lb://payment-server :表示使用負載均衡的方式調用該服務

  • path 意思就是,路徑相匹配則進行路由跳轉

  • After意思為,在指定時間后才可以訪問,之前訪問為404

時間到了后,根據暴露的端口信息得知:負載均衡調用服務

 

 

 

 

before和between

  • 這兩個和上面after都是控制時間的,顧名思義:

before: 與after類似,他說在指定時間之前的才可以訪問 between: 需要指定兩個時間,在他們之間的時間才可以訪問

cookie

  • cookie:只有包含某些指定cookie(key,value),的請求才可以路由

現在我們將配置文件修改為如下

  
gateway:
      routes:
        - id: test1
          uri: lb://payment-server
          predicates:
            - Path=/payment/test1/**
#            - After=2020-08-30T14:37:20.465+08:00[Asia/Shanghai]
            - Cookie=username,test

表示:只有cookie中包含了username這個key,且值為test才路由

在不加cookie的時候會報404

瀏覽器打開控制台,鍵入以下命令,添加cookie再訪問

document.cookie="username=test";

header

  • header:只有包含指定請求頭的請求,才可以路由

  • 現在我們將配置文件修改為如下

  
 gateway:
      routes:
        - id: test1
          uri: lb://payment-server
          predicates:
            - Path=/payment/test1/**
#            - After=2020-08-30T14:37:20.465+08:00[Asia/Shanghai]
#            - Cookie=username,test
            - Header=ninja,\d+

Header 接受兩個參數,第一個參數為頭的名稱,第二個參數為一個正則表達式

以上的配置便是,請求頭中需有一個請求頭key為ninja,且值為數字類型的值時才路由,

host

  • host:只有攜帶請求頭中指定的Host才可以進行路由

  • 現在我們將配置文件修改為如下 

gateway:
      routes:
        - id: test1
          uri: lb://payment-server
          predicates:
            - Path=/payment/test1/**
#            - After=2020-08-30T14:37:20.465+08:00[Asia/Shanghai]
#            - Cookie=username,test
#            - Header=ninja,\d+
            - Host= www.ninja.com
  • 以上的配置便是,請求頭Host的值必須為www.ninja.com時才路由,其余一律不路由,

  • 這個可以使用通配符方式比如:www.ninja.**,也是可以的

  • 測試圖為如下所示

由於往下類型眾多,我就不一一截圖演示了,做詳細的文字說明,不懂就點我

method

  • method:指定請求類型才可路由,比如post,get等

  • 配置文件修改為如下所示

    gateway:
      routes:
        - id: test1
          uri: lb://payment-server
          predicates:
            - Path=/payment/test1/**
#            - After=2020-08-30T14:37:20.465+08:00[Asia/Shanghai]
#            - Cookie=username,test
#            - Header=ninja,\d+
#            - Host= www.ninja.com
            - Method=GET

Query

  • query:必須帶有請求參數才可以訪問

  • 配置文件修改為如下所示

    gateway:
      routes:
        - id: test1
          uri: lb://payment-server
          predicates:
            - Path=/payment/test1/**
#            - After=2020-08-30T14:37:20.465+08:00[Asia/Shanghai]
#            - Cookie=username,test
#            - Header=ninja,\d+
#            - Host= www.ninja.com
#            - Method=GET
            - Query=username,\d+
  • 上面的規則為,請求中需攜帶請求參數key為username,且值為整數的值才進行路由

基本上大致的斷言類型我們以及知道了,下面對另一個概念進行講解說明:過濾器

過濾器Filter

filter可用於修改的http請求和返回的http響應,相當於就是一個pre 一個post

單一過濾器(GatewayFilter)

也就是我們配置在某個路由規則中的過濾器,對單個路由發生作用,Gateway一共內置了20多個過濾器,分別對頭部過濾器、 路徑類過濾器、 Hystrix過濾器和變更請求URL的過濾器, 還有參數和狀態碼等其他類型的過濾器。這里就不一一說明了,我們挑幾個常用的講解一番,其余就不做講解了,當個人吧!

  • 配置文件修改為如下所示

gateway:
  routes:
    - id: test1
      uri: lb://payment-server
      filters:
        - AddRequestHeader=ninja, ninja_test                #添加請求頭
        - AddResponseHeader=ninja_response,ninja_test       #添加響應頭
        - RewritePath=/payment/(?<segment>.*), /$\{segment} #請求路徑重寫
      predicates:
        - Path=/payment/payment/test1/**

測試之前想一想

  • 服務的提供者我們一直沒有做任何改變

  • 在網關中,通過斷言對請求url做了匹配

  • 然后我們使用過濾器對請求路徑做了重寫

    • /payment/(?<segment>.*), /${segment} ???

    • 第一個參數為原請求url,即是采用通配符的方式載入,

    • 第二個參數為重寫后的請求url:/${segment},為通配符的占位符

      • 根據上面我們對第一個參數的解讀,/${segment} 占位符替換即為:/payment/test1/11111

好了,更多的過濾器就面向百度吧,這里就不啰嗦了

全局過濾器(GlobalFilter)

  • 全局過濾器不再針對單個路由規則,全局過濾器無需在配置文件中配置,為請求業務以及路由的URI轉換為真實業務服務的請求地址的核心過濾器,不需要配置,系統初始化時加載,並作用在每個路由上。

自定義過濾器(局部和全局)

  • 除了上面網關提供的全局過濾器外,還可以自定義過濾器這也是我們經常使用的功能,下面詳細說明一下

  • 全局過濾器之自定義過濾器,我們需要實現兩個接口:GlobalFilter, Ordered

  • 局部過濾器子自定義過濾器,我們也需要實現兩個接口:GatewayFilter, Ordered

  • 都是重寫兩個函數,一個filter為我們的業務函數,一個表示當前過濾器的執行級別的函數

  • 如何運用局部 / 全局過濾器 ?

    • 全局過濾器:因為無需掛載到某個路由上,全局生效,無需額外編碼和配置

    • 局部過濾器:需要編碼指定某個路由,局部生效,需要額外的編碼

下面,我們分別來寫兩三個過濾器玩一玩

package com.ninja.gateway.custom;
​
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
​
/**
 * @Description 全局過濾器,前置與后置過濾器
 * @Author Ninja
 * @Date 2020/8/31
 **/
​
@Component
public class PreAndPostGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("------this is a pre filter");
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            System.out.println("------this is a post filter");
        }));
    }
​
    @Override
    public int getOrder() {
        //定義過濾器執行順序
        //返回值越小,越靠前執行
        return -1;
    }
}
package com.ninja.gateway.custom;
​
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
​
/**
 * @Description 局部過濾器:遠程調用耗時記錄
 * @Author Ninja
 * @Date 2020/8/31
 **/
​
@Component
public class TimeCountNoGlaobalFilter implements GatewayFilter, Ordered {
​
    private static final String REQUEST_TIME_BEGIN = "requestTimeBegin";
​
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //記錄請求開始時間
        exchange.getAttributes().put(REQUEST_TIME_BEGIN, System.currentTimeMillis());
​
        return chain.filter(exchange).then(Mono.fromRunnable(new Runnable() {
            @Override
            public void run() {
                Long startTime = exchange.getAttribute(REQUEST_TIME_BEGIN);
                if (startTime != null) {
                    //打印
                    System.out.println(exchange.getRequest().getURI() + " 耗時" + (System.currentTimeMillis() - startTime));
                }
            }
        }));
    }
​
    @Override
    public int getOrder() {
        //定義過濾器執行順序
        //返回值越小,越靠前執行
        return 0;
    }
}
package com.ninja.gateway.custom;
​
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
​
/**
 * @Description 全局過濾器
 * @Author Ninja
 * @Date 2020/8/31
 **/
​
@Component
public class UriGlobalFilter implements GlobalFilter, Ordered {
​
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String path = exchange.getRequest().getURI().getPath();
        System.out.println("UrlFilter攔截器已攔截,url:" + path);
        //攔截請求,直接響應
        //return exchange.getResponse().setComplete();
        //放行請求
        return chain.filter(exchange);
    }
​
    @Override
    public int getOrder() {
        //定義過濾器執行順序
        //返回值越小,越靠前執行
        return 1;
    }
}

上面我寫了三個過濾器,分別為:

  • PreAndPostGlobalFilter:全局過濾器,直接生效

  • TimeCountNoGlaobalFilter:局部過濾器,需要額外編碼指定路由

  • UriGlobalFilter:全局過濾器,直接生效

下面我們對唯一的局部過濾器進行綁定路由的編碼

package com.ninja.gateway.config;
​
import com.ninja.gateway.custom.TimeCountNoGlaobalFilter;
import com.ninja.gateway.custom.UriGlobalFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.GatewayFilterSpec;
import org.springframework.cloud.gateway.route.builder.PredicateSpec;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.cloud.gateway.route.builder.UriSpec;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
​
import java.util.function.Function;
​
/**
 * @Description 將自定義局部filter注冊到路由中
 * @Author Ninja
 * @Date 2020/8/31
 **/
@Configuration
public class FilterEureka {
​
    @Bean
    public RouteLocator getRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes().
                route(new Function<PredicateSpec, Route.AsyncBuilder>() {
                    @Override
                    public Route.AsyncBuilder apply(PredicateSpec predicateSpec) {
                        return predicateSpec
                                .path("/payment/payment/test1/**")
                                .filters(new Function<GatewayFilterSpec, UriSpec>() {
                                    @Override
                                    public UriSpec apply(GatewayFilterSpec gatewayFilterSpec) {
                                        return gatewayFilterSpec.stripPrefix(1).filter( new TimeCountNoGlaobalFilter());
                                    }
                                })
                                .uri("lb://payment-server")
                                .id("test1)");
​
                    }
                }).build();
    }
​
}
  • 仔細看看,無非就是指定了id,path 和 uri,使其綁定到了該路由上,下面我們啟動項目測試一把

可見全局過濾器和局部過濾器都已經生效,至此 畢!


免責聲明!

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



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