萬字長文:SpringCloud gateway入門學(xué)習(xí)&實(shí)踐

官方文檔:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#configuration

文中涉及到了一些模塊代碼沒有給出拐格,我一并上傳到github了璧眠,可以整個項(xiàng)目clone下來進(jìn)行調(diào)試。

地址:https://github.com/stronglxp/springcloud-test

在這里插入圖片描述

1降瞳、GateWay是什么

1.1 概念

Cloud全家桶中有個很重要的組件就是網(wǎng)關(guān)衙传,在1.x版本中都是采用的Zuul網(wǎng)關(guān)决帖。但在2.x版本中,zuul的升級一直跳票蓖捶,SpringCloud最后自己研發(fā)了一個網(wǎng)關(guān)替代Zuul地回。

Gateway是在Spring生態(tài)系統(tǒng)之上構(gòu)建的API網(wǎng)關(guān)服務(wù),基于Spring 5俊鱼,Spring Boot 2和Project Reactor等技術(shù)刻像。

Gateway旨在提供一種簡單而有效的方式來對API進(jìn)行路由,以及提供一些強(qiáng)大的過濾器功能并闲,例如:熔斷细睡、限流、重試等帝火。

SpringCloud Gateway是Spring Cloud的一個全新項(xiàng)目溜徙,基于Spring 5.0+Spring Boot 2.0和Project Reactor等技術(shù)開發(fā)的網(wǎng)關(guān),它旨在為微服務(wù)架構(gòu)提供—種簡單有效的統(tǒng)一的API路由管理方式犀填。

SpringCloud Gateway作為Spring Cloud 生態(tài)系統(tǒng)中的網(wǎng)關(guān)蠢壹,目標(biāo)是替代Zuul,在Spring Cloud 2.0以上版本中宏浩,沒有對新版本的Zul 2.0以上最新高性能版本進(jìn)行集成,仍然還是使用的Zuul 1.x非Reactor模式的老版本靠瞎。而為了提升網(wǎng)關(guān)的性能比庄,SpringCloud Gateway是基于WebFlux框架實(shí)現(xiàn)的求妹,而WebFlux框架底層則使用了高性能的Reactor模式通信框架Netty。

Spring Cloud Gateway的目標(biāo)提供統(tǒng)一的路由方式且基于 Filter鏈的方式提供了網(wǎng)關(guān)基本的功能佳窑,例如:安全制恍,監(jiān)控/指標(biāo),和限流神凑。

1.2 作用

  • 方向代理
  • 鑒權(quán)
  • 流量控制
  • 熔斷
  • 日志監(jiān)控

1.3 微服務(wù)架構(gòu)中網(wǎng)關(guān)的位置

在這里插入圖片描述

2净神、GateWay非阻塞異步模型

2.1 為什么選擇Gateway?

netflix不太靠譜,zuul2.0一直跳票溉委,遲遲不發(fā)布鹃唯。

  • 一方面因?yàn)閆uul1.0已經(jīng)進(jìn)入了維護(hù)階段,而且Gateway是SpringCloud團(tuán)隊(duì)研發(fā)的瓣喊,是親兒子產(chǎn)品坡慌,值得信賴。而且很多功能Zuul都沒有用起來也非常的簡單便捷藻三。
  • Gateway是基于異步非阻塞模型上進(jìn)行開發(fā)的洪橘,性能方面不需要擔(dān)心。雖然Netflix早就發(fā)布了最新的Zuul 2.x棵帽,但Spring Cloud貌似沒有整合計(jì)劃熄求。而且Netflix相關(guān)組件都宣布進(jìn)入維護(hù)期;不知前景如何?
  • 多方面綜合考慮Gateway是很理想的網(wǎng)關(guān)選擇逗概。

SpringCloud Gateway具有如下特性

  • 基于Spring Framework 5弟晚,Project Reactor和Spring Boot 2.0進(jìn)行構(gòu)建;
  • 動態(tài)路由:能夠匹配任何請求屬性仗谆;
  • 可以對路由指定Predicate (斷言)和Filter(過濾器)指巡;
  • 集成Hystrix的斷路器功能;
  • 集成Spring Cloud 服務(wù)發(fā)現(xiàn)功能隶垮;
  • 易于編寫的Predicate (斷言)和Filter (過濾器)藻雪;
  • 請求限流功能;
  • 支持路徑重寫狸吞。

SpringCloud Gateway與Zuul的區(qū)別

  • 在SpringCloud Finchley正式版之前勉耀,Spring Cloud推薦的網(wǎng)關(guān)是Netflix提供的Zuul。
  • Zuul 1.x蹋偏,是一個基于阻塞I/O的API Gateway便斥。
  • Zuul 1.x基于Servlet 2.5使用阻塞架構(gòu)它不支持任何長連接(如WebSocket)Zuul的設(shè)計(jì)模式和Nginx較像,每次I/О操作都是從工作線程中選擇一個執(zhí)行威始,請求線程被阻塞到工作線程完成枢纠,但是差別是Nginx用C++實(shí)現(xiàn),Zuul用Java實(shí)現(xiàn)黎棠,而JVM本身會有第-次加載較慢的情況晋渺,使得Zuul的性能相對較差镰绎。
  • Zuul 2.x理念更先進(jìn),想基于Netty非阻塞和支持長連接木西,但SpringCloud目前還沒有整合畴栖。Zuul .x的性能較Zuul 1.x有較大提升。在性能方面八千,根據(jù)官方提供的基準(zhǔn)測試,Spring Cloud Gateway的RPS(每秒請求數(shù))是Zuul的1.6倍吗讶。
  • Spring Cloud Gateway建立在Spring Framework 5、Project Reactor和Spring Boot2之上恋捆,使用非阻塞API照皆。
  • Spring Cloud Gateway還支持WebSocket,并且與Spring緊密集成擁有更好的開發(fā)體驗(yàn)

2.2 Zuul1.x模型

Springcloud中所集成的Zuul版本鸠信,采用的是Tomcat容器纵寝,使用的是傳統(tǒng)的Serviet IO處理模型。

Servlet的生命周期星立?servlet由servlet container進(jìn)行生命周期管理爽茴。

  • container啟動時構(gòu)造servlet對象并調(diào)用servlet init()進(jìn)行初始化;
  • container運(yùn)行時接受請求绰垂,并為每個請求分配一個線程(一般從線程池中獲取空閑線程)然后調(diào)用service)室奏;
  • container關(guān)閉時調(diào)用servlet destory()銷毀servlet。
在這里插入圖片描述

上述模式的缺點(diǎn):

Servlet是一個簡單的網(wǎng)絡(luò)IO模型劲装,當(dāng)請求進(jìn)入Servlet container時胧沫,Servlet container就會為其綁定一個線程,在并發(fā)不高的場景下這種模型是適用的占业。但是一旦高并發(fā)(如抽風(fēng)用Jmeter壓)绒怨,線程數(shù)量就會上漲,而線程資源代價是昂貴的(上線文切換谦疾,內(nèi)存消耗大)嚴(yán)重影響請求的處理時間南蹂。在一些簡單業(yè)務(wù)場景下,不希望為每個request分配一個線程念恍,只需要1個或幾個線程就能應(yīng)對極大并發(fā)的請求六剥,這種業(yè)務(wù)場景下servlet模型沒有優(yōu)勢。

所以Zuul 1.X是基于servlet之上的一個阻塞式處理模型峰伙,即Spring實(shí)現(xiàn)了處理所有request請求的一個servlet (DispatcherServlet)并由該servlet阻塞式處理處理疗疟。所以SpringCloud Zuul無法擺脫servlet模型的弊端。

2.3 GateWay模型

WebFlux是什么瞳氓?官方文檔

傳統(tǒng)的Web框架策彤,比如說: Struts2,SpringMVC等都是基于Servlet APl與Servlet容器基礎(chǔ)之上運(yùn)行的。

但是在Servlet3.1之后有了異步非阻塞的支持店诗。而WebFlux是一個典型非阻塞異步的框架叽赊,它的核心是基于Reactor的相關(guān)API實(shí)現(xiàn)的。相對于傳統(tǒng)的web框架來說必搞,它可以運(yùn)行在諸如Netty,Undertow及支持Servlet3.1的容器上囊咏。非阻塞式+函數(shù)式編程(Spring 5必須讓你使用Java 8)恕洲。

Spring WebFlux是Spring 5.0 引入的新的響應(yīng)式框架,區(qū)別于Spring MVC梅割,它不需要依賴Servlet APl霜第,它是完全異步非阻塞的,并且基于Reactor來實(shí)現(xiàn)響應(yīng)式流規(guī)范户辞。

Spring Cloud Gateway requires the Netty runtime provided by Spring Boot and Spring Webflux. It does not work in a traditional Servlet Container or when built as a WAR.

3泌类、GateWay工作流程

3.1 三大核心概念

  • Route(路由) - 路由是構(gòu)建網(wǎng)關(guān)的基本模塊,它由ID,目標(biāo)URI,一系列的斷言和過濾器組成,如斷言為true則匹配該路由;
  • Predicate(斷言) - 參考的是Java8的java.util.function.Predicate底燎,開發(fā)人員可以匹配HTTP請求中的所有內(nèi)容(例如請求頭或請求參數(shù)),如果請求與斷言相匹配則進(jìn)行路由刃榨;
  • Filter(過濾) - 指的是Spring框架中GatewayFilter的實(shí)例,使用過濾器,可以在請求被路由前或者之后對請求進(jìn)行修改。
在這里插入圖片描述

web請求双仍,通過一些匹配條件枢希,定位到真正的服務(wù)節(jié)點(diǎn)。并在這個轉(zhuǎn)發(fā)過程的前后朱沃,進(jìn)行一些精細(xì)化控制苞轿。

predicate就是我們的匹配條件;而fliter逗物,就可以理解為一個無所不能的攔截器搬卒。有了這兩個元素,再加上目標(biāo)uri翎卓,就可以實(shí)現(xiàn)一個具體的路由了契邀。

3.2 GateWay工作流程

在這里插入圖片描述

Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a route, it is sent to the Gateway Web Handler. This handler runs the request through a filter chain that is specific to the request. The reason the filters are divided by the dotted line is that filters can run logic both before and after the proxy request is sent. All “pre” filter logic is executed. Then the proxy request is made. After the proxy request is made, the “post” filter logic is run.

客戶端向Spring Cloud Gateway發(fā)出請求。然后在Gateway Handler Mapping 中找到與請求相匹配的路由莲祸,將其發(fā)送到GatewayWeb Handler蹂安。

Handler再通過指定的過濾器鏈來將請求發(fā)送到我們實(shí)際的服務(wù)執(zhí)行業(yè)務(wù)邏輯,然后返回锐帜。

過濾器之間用虛線分開是因?yàn)檫^濾器可能會在發(fā)送代理請求之前(“pre”)或之后(“post")執(zhí)行業(yè)務(wù)邏輯田盈。

Filter在“pre”類型的過濾器可以做參數(shù)校驗(yàn)、權(quán)限校驗(yàn)缴阎、流量監(jiān)控允瞧、日志輸出、協(xié)議轉(zhuǎn)換等,在“post”類型的過濾器中可以做響應(yīng)內(nèi)容述暂、響應(yīng)頭的修改痹升,日志的輸出,流量監(jiān)控等有著非常重要的作用畦韭。

核心邏輯:路由轉(zhuǎn)發(fā) + 執(zhí)行過濾器鏈疼蛾。

4、GateWay模塊搭建

創(chuàng)建新module:cloud-gateway

pom.xml文件如下

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.codeliu</groupId>
        <artifactId>springcloud-test</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>cloud-gateway</artifactId>

    <dependencies>
        <!--引入cloud-api-common模塊-->
        <dependency>
            <groupId>com.codeliu</groupId>
            <artifactId>cloud-api-common</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

application.yml文件如下艺配,注冊到eureka服務(wù)器

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
    
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:9001/eureka

啟動類如下

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class CloudGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(CloudGatewayApplication.class, args);
    }
}

在provider模塊中察郁,我們有一個接口如下

在這里插入圖片描述

可以通過配置網(wǎng)關(guān)訪問該接口

spring:
  application:
    name: cloud-gateway
  # 網(wǎng)關(guān)配置
  cloud:
    gateway:
      routes:
        - id: provider-payment-route1  # 路由的id,沒有固定規(guī)則但要求唯一转唉,建議配合服務(wù)名
          uri: http://localhost:8001   # 匹配后提供服務(wù)的路由地址
          predicates:
            - Path=/payment/**         # 斷言皮钠,路徑相匹配的路由

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:9001/eureka

啟動Eureka服務(wù)器,啟動provider服務(wù)赠法,然后啟動gateway服務(wù)麦轰,通過provider訪問該接口和通過gateway訪問該接口返回的結(jié)果一致。

5砖织、GateWay配置路由的兩種方式

(1)通過yml文件配置款侵,上一章就是這樣搞的。

(2)代碼中注入RouteLocator的Bean

官方樣例

RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
    .maxTrustedIndex(1);

...

.route("direct-route",
    r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
        .uri("https://downstream1")
.route("proxied-route",
    r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
        .uri("https://downstream2")
)

我們可以自己寫一個訪問百度新聞網(wǎng)

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;

/**
 * 配置路由有兩種方式:1侧纯、通過配置文件喳坠。2、通過配置類
 * 這里通過配置類配置路由
 */
@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        // 第一個參數(shù)是路由的唯一id
        // http://localhost:9527/guonei  =>  http://news.baidu.com/guonei
        routes.route("path_route_baidu",
                        r -> r.path("/guonei")
                        .uri("http://news.baidu.com/guonei")).build();
        return routes.build();
    }
}

瀏覽器輸入http://localhost:9527/guonei茂蚓,返回http://news.baidu.com/guonei相同的頁面壕鹉。

6、GateWay配置動態(tài)路由

默認(rèn)情況下Gateway會根據(jù)注冊中心注冊的服務(wù)列表聋涨,以注冊中心上微服務(wù)名為路徑創(chuàng)建動態(tài)路由進(jìn)行轉(zhuǎn)發(fā)晾浴,從而實(shí)現(xiàn)動態(tài)路由的功能(不寫死一個地址)。

修改GateWay模塊的yml文件

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
# 網(wǎng)關(guān)配置
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true   # 開啟從注冊中心動態(tài)創(chuàng)建路由的功能牍白,利用微服務(wù)名進(jìn)行路由
      routes:
        - id: provider-payment-route1  # 路由的id脊凰,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名
          # uri: http://localhost:8001   # 匹配后提供服務(wù)的路由地址
          uri: lb://provider-payment   # 需要注意的是uri的協(xié)議為lb茂腥,表示啟用Gateway的負(fù)載均衡功能狸涌。lb://serviceName是spring cloud gateway在微服務(wù)中自動為我們創(chuàng)建的負(fù)載均衡uri。
          predicates:
            - Path=/payment/**         # 斷言最岗,路徑相匹配的路由

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:9001/eureka

啟動Eureka服務(wù)器帕胆,啟動兩個provider服務(wù),啟動GateWay服務(wù)般渡,重復(fù)訪問http://localhost:9527/payment/1懒豹,會輪詢訪問兩個provider服務(wù)的接口芙盘。

7、GateWay內(nèi)置的Predicate

文檔鏈接

Spring Cloud Gateway將路由匹配作為Spring WebFlux HandlerMapping基礎(chǔ)架構(gòu)的一部分脸秽。

Spring Cloud Gateway包括許多內(nèi)置的Route Predicate工廠儒老。所有這些Predicate都與HTTP請求的不同屬性匹配。多個RoutePredicate工廠可以進(jìn)行組合记餐。

Spring Cloud Gateway創(chuàng)建Route 對象時驮樊,使用RoutePredicateFactory 創(chuàng)建 Predicate對象,Predicate 對象可以賦值給Route片酝。Spring Cloud Gateway包含許多內(nèi)置的Route Predicate Factories巩剖。

所有這些謂詞都匹配HTTP請求的不同屬性。多種謂詞工廠可以組合钠怯,并通過邏輯and。

常用的Route Predicate Factory

(1)The After Route Predicate Factory

(2)The Before Route Predicate Factory

(3)The Between Route Predicate Factory

(4)The Cookie Route Predicate Factory

(5)The Header Route Predicate Factory

(6)The Host Route Predicate Factory

(7)The Method Route Predicate Factory

(8)The Path Route Predicate Factory

(9)The Query Route Predicate Factory

(10)The RemoteAddr Route Predicate Factory

(11)The weight Route Predicate Factory

可以嘗試在yml中配置一些predicate

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
# 網(wǎng)關(guān)配置
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true   # 開啟從注冊中心動態(tài)創(chuàng)建路由的功能曙聂,利用微服務(wù)名進(jìn)行路由
      routes:
        - id: provider-payment-route1  # 路由的id晦炊,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名
          # uri: http://localhost:8001   # 匹配后提供服務(wù)的路由地址
          uri: lb://provider-payment   # 需要注意的是uri的協(xié)議為lb宁脊,表示啟用Gateway的負(fù)載均衡功能断国。lb://serviceName是spring cloud gateway在微服務(wù)中自動為我們創(chuàng)建的負(fù)載均衡uri。
          predicates:
            - Path=/payment/**         # 斷言榆苞,路徑相匹配的路由

        # gateway內(nèi)置的路由斷言:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories
        - id: after-route
          uri: https://example.org
          predicates:
            # 對于同一個path稳衬,從上到下匹配,匹配成功后坐漏,后面的規(guī)則就不生效了
            - Path=/example/**
            # 這個時間后才生效
            - After=2021-07-08T10:25:20.760+08:00[Asia/Shanghai]

        - id: between-route
          uri: https://example.org
          predicates:
            - Path=/example/**
            - Between=2021-07-08T10:25:20.760+08:00[Asia/Shanghai], 2021-07-09T10:25:20.760+08:00[Asia/Shanghai]

        - id: cookie-route
          uri: https://example.org
          predicates:
            - Path=/example/**
            - Cookie=chocolate, ch.p

        - id: header-route
          uri: https://example.org
          predicates:
            - Path=/example/**
            - Header=X-Request-Id, \d+

eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:9001/eureka

可以使用ZonedDateTime生成上面這種格式的時間

// 生成gateway內(nèi)置路由斷言工廠需要的時間戳格式 2021-07-05T10:25:20.760+08:00[Asia/Shanghai]
ZonedDateTime zbj = ZonedDateTime.now();
System.out.println(zbj);

上面我們加了4個內(nèi)置的斷言薄疚,分別是After、Between赊琳、Cookie街夭、Header,源uri是: https://example.org躏筏,匹配的uri是:/example/**

通過下面的請求進(jìn)行測試

# 該命令相當(dāng)于發(fā)get請求板丽,且沒帶cookie
curl http://localhost:9527/example

# 帶cookie的
curl http://localhost:9527/example --cookie "chocolate=chip"

# 帶指定請求頭的參數(shù)的CURL命令
curl http://localhost:9527/example -H "X-Request-Id:123"

測試發(fā)現(xiàn):對于同一個path,從上往下匹配規(guī)則趁尼,匹配上了就不會往下走了埃碱。

總結(jié):predicate就是為了實(shí)現(xiàn)一組匹配規(guī)則,讓請求過來找到對應(yīng)的Route進(jìn)行處理酥泞。

8砚殿、GateWay的Filter

文檔鏈接

路由過濾器可用于修改進(jìn)入的HTTP請求和返回的HTTP響應(yīng),路由過濾器只能指定路由進(jìn)行使用芝囤。Spring Cloud Gateway內(nèi)置了多種路由過濾器瓮具,他們都由GatewayFilter的工廠類來產(chǎn)生荧飞。

Spring Cloud Gateway的Filter:

  • 生命周期:
    • pre
    • post
  • 種類(具體看官方文檔):
    • GatewayFilter - 有31種
    • GlobalFilter - 有10種

如果我們要自定義一個全局GlobalFilter,需要實(shí)現(xiàn)GlobalFilter, Ordered接口名党。

比如我們實(shí)現(xiàn)一個Filter叹阔,所有通過該網(wǎng)關(guān)進(jìn)行請求都需要帶上特定的字符串才行

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
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.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Date;

/**
 * 這里自定義一個全局filter,實(shí)現(xiàn) GlobalFilter 和 Ordered接口传睹,所有的請求訪問都要先經(jīng)過這個全局 filter驗(yàn)證
 */
@Component
@Slf4j
public class MyLogGatewayFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("come in MyLogGatewayFilter: " + new Date());
        String name = exchange.getRequest().getQueryParams().getFirst("name");
        if (StringUtils.isBlank(name)) {
            log.info("非法用戶!");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        // 繼續(xù)下一個filter
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

在上面的filter中我們規(guī)定所有請求過來都需要帶上name字段并且值不能為空耳幢。

訪問:http://localhost:9527/payment/1,后臺打印【非法用戶!】欧啤,訪問:http://localhost:9527/payment/1?name=a睛藻,返回結(jié)果。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末邢隧,一起剝皮案震驚了整個濱河市店印,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌倒慧,老刑警劉巖按摘,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異纫谅,居然都是意外死亡炫贤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門付秕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兰珍,“玉大人,你說我怎么就攤上這事询吴÷雍樱” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵猛计,是天一觀的道長口柳。 經(jīng)常有香客問我,道長有滑,這世上最難降的妖魔是什么跃闹? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮毛好,結(jié)果婚禮上望艺,老公的妹妹穿的比我還像新娘。我一直安慰自己肌访,他們只是感情好找默,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吼驶,像睡著了一般惩激。 火紅的嫁衣襯著肌膚如雪店煞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天风钻,我揣著相機(jī)與錄音顷蟀,去河邊找鬼。 笑死骡技,一個胖子當(dāng)著我的面吹牛鸣个,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播布朦,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼囤萤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了是趴?” 一聲冷哼從身側(cè)響起涛舍,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎唆途,沒想到半個月后富雅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡窘哈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了亭敢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滚婉。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖帅刀,靈堂內(nèi)的尸體忽然破棺而出让腹,到底是詐尸還是另有隱情,我是刑警寧澤扣溺,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布骇窍,位于F島的核電站,受9級特大地震影響锥余,放射性物質(zhì)發(fā)生泄漏腹纳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一驱犹、第九天 我趴在偏房一處隱蔽的房頂上張望嘲恍。 院中可真熱鬧,春花似錦雄驹、人聲如沸佃牛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俘侠。三九已至象缀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間爷速,已是汗流浹背央星。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓园担,卻偏偏與公主長得像技矮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子率寡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 什么是微服務(wù)網(wǎng)關(guān) ? 在微服務(wù)眾多的服務(wù)的治理過程中,服務(wù)網(wǎng)關(guān)的作用在微服務(wù)框架中可以提供統(tǒng)一入口、鑒權(quán)校驗(yàn)州泊、...
    Martain閱讀 18,876評論 0 6
  • Spring 官方最終還是按捺不住推出了自己的網(wǎng)關(guān)組件:Spring Cloud Gateway ,相比之前我們使...
    gmdqtd閱讀 1,354評論 0 0
  • SpringCloud Gateway 性能 硬件環(huán)境:三臺機(jī)器漂洋,分別運(yùn)行服務(wù)端程序遥皂,網(wǎng)關(guān)程序和壓測程序CPU: ...
    liuliuzo閱讀 8,157評論 0 2
  • 概述 SpringCloud全家桶中有個很重要的組件就是網(wǎng)關(guān),在1.x版本中都是采用Zuul網(wǎng)關(guān)刽漂; 但是2.x版本...
    JavaGym閱讀 555評論 0 1
  • 概念簡介 Cloud全家桶中有個很重要的組件就是網(wǎng)關(guān),在1.x版本中都是采用Zuul網(wǎng)關(guān);但是在2.x版本中,zu...
    木木子丶閱讀 524評論 0 1