熬夜肝了這篇Spring Cloud Gateway的功能及綜合使用
- 2020 年 12 月 27 日
- 筆記
- JAVA, Spring Cloud, Spring Cloud面試題, 程式設計師, 編程
前言
SpringCloud 是微服務中的翹楚,最佳的落地方案。
Spring Cloud Gateway 是 Spring Cloud 新推出的網關框架,之前是 Netflix Zuul。網關通常在項目中為了簡化
前端的調用邏輯,同時也簡化內部服務之間互相調用的複雜度;具體作用就是轉發服務,接收並轉發所有內外
部的客戶端調用;其他常見的功能還有許可權認證,限流控制等等。
本部落格會提到網關的基本轉發功能,熔斷功能,限流功能以及功能的綜合使用。
源碼
GitHub地址://github.com/intomylife/SpringCloud
環境
JDK 1.8.0 +
Maven 3.0 +
SpringBoot 2.0.3
SpringCloud Finchley.RELEASE
Redis 3.0 +
開發工具
IntelliJ IDEA
正文
commons 工程
commons 工程 – POM 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="//maven.apache.org/POM/4.0.0" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="//maven.apache.org/POM/4.0.0 //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 下聲明相應的版本資訊,然後在 dependency 下引用的時候用 ${} 就可以引入該版本 jar 包了 -->
<properties>
<!-- 編碼 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- jdk -->
<java.version>1.8</java.version>
<!-- SpringBoot -->
<platform-bom.version>Cairo-SR3</platform-bom.version>
<!-- SpringCloud -->
<spring-cloud-dependencies.version>Finchley.RELEASE</spring-cloud-dependencies.version>
</properties>
<!-- 加入依賴 -->
<dependencies>
</dependencies>
<!-- 依賴 jar 包版本管理的管理器 -->
<!-- 如果 dependencies 里的 dependency 自己沒有聲明 version 元素,那麼 maven 就此處來找版本聲明。 -->
<!-- 如果有,就會繼承它;如果沒有就會報錯,告訴你沒有版本資訊 -->
<!-- 優先順序:如果 dependencies 里的 dependency 已經聲明了版本資訊,就不會生效此處的版本資訊了 -->
<dependencyManagement>
<dependencies>
<!-- SpringBoot -->
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>${platform-bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud -->
<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>
配置一些共用依賴
commons 工程 – 項目結構
service 工程
**① 此工程下有四個模組:一個註冊中心,一個網關以及兩個提供者
② 兩個提供者除埠不一致以外,其他程式碼基本一致
registry-service(註冊中心)
registry-service – POM 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="//maven.apache.org/POM/4.0.0" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="//maven.apache.org/POM/4.0.0 //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下聲明相應的版本資訊,然後在dependency下引用的時候用 ${} 就可以引入該版本jar包了 -->
<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 依賴
registry-service – application.yml 配置文件
#埠
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: //${eureka.instance.hostname}:${server.port}/eureka/
這裡使用了默認的 8761 埠,當然也可以更改,不過在發現調用服務端的註冊中心地址埠要與它一致
registry-service – 啟動類
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);
}
}
在啟動類中添加 @EnableEurekaServer 註解表示此工程是註冊中心
registry-service – 啟動項目
- 項目啟動成功後訪問 //localhost:8761/ 即可看到 eureka-server 主頁面
註:由於服務工程 A 和服務工程 B 除埠不一致以外,其他程式碼基本一致,所以服務工程 B 不再贅述
a-service(服務工程 A)
a-service – POM 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="//maven.apache.org/POM/4.0.0" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="//maven.apache.org/POM/4.0.0 //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下聲明相應的版本資訊,然後在dependency下引用的時候用 ${} 就可以引入該版本jar包了 -->
<properties>
</properties>
<!-- 加入依賴 -->
<dependencies>
<!-- commons工程 依賴 -->
<dependency>
<groupId>com.zwc</groupId>
<artifactId>springcloud-gateway-commons</artifactId>
<version>1.0</version>
</dependency>
<!-- api工程 依賴 -->
<dependency>
<groupId>com.zwc</groupId>
<artifactId>springcloud-gateway-a-service-api</artifactId>
<version>1.0</version>
</dependency>
<!-- springboot web 依賴 -->
<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>
加入spring-cloud-starter-netflix-eureka-client依賴
a-service – application.yml 配置文件
#埠
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: //${eureka.instance.hostname}:8761/eureka/
注意此處配置註冊中心地址的埠為 8761 也就是上面註冊中心工程配置的埠
a-service – controller 前端控制器(提供服務)
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;
/*
* @ClassName ASayHelloController
* @Desc TODO Say Hello
* @Date 2019/5/20 23:24
* @Version 1.0
*/
@RestController
public class ASayHelloController {
/*
* @ClassName ASayHelloController
* @Desc TODO 讀取配置文件中的埠
* @Date 2019/5/20 23:24
* @Version 1.0
*/
@Value("${server.port}")
private String port;
/*
* @ClassName ASayHelloController
* @Desc TODO Say Hello
* @Date 2019/5/20 23:24
* @Version 1.0
*/
@RequestMapping("/hello")
public String hello(){
return "Hello!I'm a. port:" + port;
}
/*
* @ClassName ASayHelloController
* @Desc TODO 接收從網關傳入的參數
* @Date 2019/6/23 16:28
* @Version 1.0
*/
@RequestMapping("/name")
public String name(String name){
return "My name is " + name + ". aaa";
}
/*
* @ClassName ASayHelloController
* @Desc TODO 接收從網關傳入的參數
* @Date 2019/6/23 16:52
* @Version 1.0
*/
@RequestMapping("/age")
public String age(String age){
return "I am " + age + " years old this year. aaa";
}
/*
* @ClassName ASayHelloController
* @Desc TODO 接收從網關傳入的參數
* @Date 2019/6/29 22:00
* @Version 1.0
*/
@RequestMapping("/routeAll")
public String routeAll(String pass) {
return "Can I pass? " + pass + "! port:" + port;
}
}
提供輸出字元串服務,供網關調用
a-service – 啟動類
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);
}
}
添加 @EnableEurekaClient 註解表示此工程可以向註冊中心提供服務
a-service – 啟動項目
2. 項目啟動成功後訪問://localhost:9000/hello
-
輸出內容:’Hello!I’m a. port:9000′
-
同樣啟動服務工程 B後,刷新 //localhost:8761/(註冊中心)
-
項目啟動成功後訪問://localhost:9001/hello
-
輸出內容:’Hello!I’m b. port:9001′
-
其他介面是下面網關服務啟動後轉發調用的,也是本部落格的重頭戲
master-service(網關)
master-service – POM 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="//maven.apache.org/POM/4.0.0" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="//maven.apache.org/POM/4.0.0 //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下聲明相應的版本資訊,然後在 dependency 下引用的時候用 ${} 就可以引入該版本 jar 包了 -->
<properties>
<!-- ali json -->
<fastjson.version>1.2.47</fastjson.version>
</properties>
<!-- 加入依賴 -->
<dependencies>
<!-- 提供者消費者 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
<!-- hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<!-- ali json依賴 -->
<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>
加入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 配置文件
#埠
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: //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: //${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: //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: //${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: //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: //${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: //${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 時調用的方法 //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: //${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: //${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 時調用的方法 //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: //${eureka.instance.hostname}:8761/eureka/
logging:
level:
# log 級別
org.springframework.cloud.gateway: debug
注意配置註冊中心地址的埠都為 8761 也就是上面註冊中心工程配置的埠
每一對 ‘—‘ 符號中的配置文件都是單獨的,使用 spring.profiles.active 指定
每一對 ‘—‘ 符號中的配置文件都只配置了一個 route(路由)
route(路由)由四部分組成,其中 filters 不是必須參數
唯一標識(ID)、目標服務地址(uri)、一組斷言(predicates)和一組過濾器組成(filters)
master-service – 簡單嘗試
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: //www.zouwencong.com
# 路由條件(predicates:斷言,匹配 HTTP 請求內容)
predicates:
## 轉發地址格式為 uri/archive
- Path=/archive
-
停止註冊中心工程(registry-service)、服務工程 A 和服務工程 B
-
把 master-service – application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_simple
-
上面配置文件內容意思是當訪問 //localhost:8000/archive (網關地址/archive)
會被轉發到 //www.zouwencong.com/archive/ (uri/archive)
-
啟動註冊中心工程(registry-service)和網關工程(master-service)
-
項目啟動成功後訪問://localhost:8000/archive
-
發現頁面會自動被跳轉到://www.zouwencong.com/archive/
-
證明服務轉發成功
master-service – 截取請求
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: //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: //${eureka.instance.hostname}:8761/eureka/
logging:
level:
# log 級別
org.springframework.cloud.gateway: debug
-
停止註冊中心工程(registry-service)和網關工程(master-service)
-
把 master-service – application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_stripPrefix
-
上面配置文件內容意思是訪問的路徑 //localhost:8000/str/archive (網關地址/str/archive)截取 /str 部分,
截取後被轉發到 //www.zouwencong.com/archive/ (uri/archive)
-
啟動註冊中心工程(registry-service)和網關工程(master-service)
-
項目啟動成功後訪問://localhost:8000/str/archive
-
發現頁面會自動被跳轉到://www.zouwencong.com/archive/
-
證明路徑被截取並服務轉發成功
master-service – 轉髮指定地址並傳入參數
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: //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: //${eureka.instance.hostname}:8761/eureka/
logging:
level:
# log 級別
org.springframework.cloud.gateway: debug
-
停止註冊中心工程(registry-service)和網關工程(master-service)
-
把 master-service – application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_uri
-
上面配置文件內容意思是訪問的路徑 //localhost:8000/name (網關地址/name)
會被轉發到 //localhost:9000/name(uri/name),並傳入 ‘name=zwc’ 參數(注意為 Get 請求)
-
啟動註冊中心工程(registry-service),網關工程(master-service)和服務工程 A(a-service)
-
項目啟動成功後訪問://localhost:8000/name
-
輸出內容:’My name is zwc. aaa’(通過網關轉發 – 參數有值)
-
打開新頁面訪問://localhost:9000/name
-
輸出內容:’My name is null. aaa’(直接訪問 – 參數沒有值)
-
證明轉髮指定地址並傳入參數成功
master-service – 轉髮指定服務並傳入參數
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: //${eureka.instance.hostname}:8761/eureka/
logging:
level:
# log 級別
org.springframework.cloud.gateway: debug
-
停止註冊中心工程(registry-service),網關工程(master-service)和服務工程 A(a-service)
-
把 master-service – application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_addRequestParameter
-
上面配置文件內容意思是訪問的路徑 //localhost:8000/age (網關地址/age)會被轉發到 //gateway-service/age(uri/age),並傳入 ‘age=three’ 參數(注意為 Get 請求)
-
注意此處的配置 uri: lb://gateway-service 與之前都有所不同,之前都是指定了明確的轉發地址,可以滿足單個服務轉發的需求,但是一般情況都會有多個服務,所以這裡是指定的服務名稱,格式為:lb://應用註冊服務名。
-
啟動註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)
-
項目啟動成功後訪問://localhost:8000/age
-
這時可能會報錯 500.錯誤資訊為 ‘Unable to find instance for gateway-service’
-
這種情況不要慌張,只是服務還沒有被註冊到註冊中心,稍等片刻再訪問
-
多次訪問://localhost:8000/age
-
輪流輸出內容:’I am three years old this year. aaa’ 和 ‘I am three years old this year. bbb’
-
此時還通過網關達到了負載均衡的效果
-
證明轉髮指定服務並傳入參數成功
master-service – 熔斷
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 時調用的方法 //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: //${eureka.instance.hostname}:8761/eureka/
logging:
level:
# log 級別
org.springframework.cloud.gateway: debug
-
停止註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)
-
把 master-service – application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_hystrix
-
上面配置文件內容意思是訪問的路徑 //localhost:8000/age (網關地址/age)會被轉發到 //gateway-service/age(uri/age),並傳入 ‘age=three’ 參數(注意為 Get 請求)
-
注意此處的配置 uri: lb://gateway-service 與之前都有所不同,之前都是指定了明確的轉發地址,可以滿足單個服務轉發的需求,但是一般情況都會有多個服務,所以這裡是指定的服務名稱,格式為:lb://應用註冊服務名。
-
此處還多配置了一個過濾器 ‘- name: Hystrix’(熔斷)
-
當請求服務出錯時,會調用 fallback,路徑為://localhost:8000/fallback (網關地址/fallback)
-
此時就需要如下前端控制器
master-service – 熔斷 – controller
package com.zwc.gateway.hystrix;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @ClassName FallbackController
* @Desc TODO 網關斷路器
* @Date 2019/6/23 19:33
* @Version 1.0
*/
@RestController
public class FallbackController {
/*
* @ClassName FallbackController
* @Desc TODO 網關斷路器
* @Date 2019/6/23 19:35
* @Version 1.0
*/
@RequestMapping("/fallback")
public String fallback() {
return "I'm Spring Cloud Gateway fallback.";
}
}
8. 啟動註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)
-
項目啟動成功後訪問://localhost:8000/age
-
輸出內容:’I’m Spring Cloud Gateway fallback.’
-
證明熔斷成功
master-service – 限流(重點,解決不生效問題)
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: //${eureka.instance.hostname}:8761/eureka/
logging:
level:
# log 級別
org.springframework.cloud.gateway: debug
-
停止註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)
-
把 master-service – application.yml 配置文件中最上面的 spring.profiles.active 的值更改route_requestRateLimiter
-
上面配置文件內容意思是訪問的路徑 //localhost:8000/age (網關地址/age)會被轉發到 //gateway-service/age(uri/age),並傳入 ‘age=three’ 參數(注意為 Get 請求)
-
注意此處還需要配置 redis 的連接資訊
-
注意此處是結合 redis 實現的限流,所以 filter 過濾器的 name 必須為 RequestRateLimiter
-
並且通過實現 KeyResolver 類來自定義限流策略,如下
master-service – 限流 – 策略
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;
/**
* @ClassName UriKeyResolver
* @Desc TODO Spring Cloud Gateway 網關限流過濾器
* @Date 2019/6/23 17:59
* @Version 1.0
*/
public class UriKeyResolver implements KeyResolver {
/*
* @ClassName UriKeyResolver
* @Desc TODO 根據請求的 uri 限流
* @Date 2019/6/29 17:25
* @Version 1.0
*/
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest().getURI().getPath());
}
}
-
啟動本地 redis(redis-server.exe) 服務
-
啟動註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)
-
項目啟動成功後訪問://localhost:8000/age
-
此時限流卻無論如何都不生效,原因有如下兩點
① redis-server 版本過低!我 Windows 本地是 redis-2.4.2 版本的,要用 3 以上的版本!!!
② 數據在 redis 中存儲的時間只有幾秒,所以得使用 monitor 指令來動態的觀察!!!
-
打開 redis-cli.exe,輸入命令 monitor
-
快速刷新地址://localhost:8000/age
-
頁面上會出現 429,redis-cli.exe 中會出現很多數據交互(request_rate_limiter.xxx 開頭的 key)
-
證明限流成功
master-service – 綜合
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 時調用的方法 //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: //${eureka.instance.hostname}:8761/eureka/
logging:
level:
# log 級別
org.springframework.cloud.gateway: debug
-
停止註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)
-
把 master-service – application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_all
-
上面配置文件內容意思是訪問的路徑 //localhost:8000/all/routeAll (網關地址/all/routeAll)截取 /all 部分,會被轉發到 //gateway-service/routeAll(uri/routeAll),並傳入 ‘pass=yes’ 參數(注意為 Get 請求)
-
啟動註冊中心工程(registry-service),網關工程(master-service)和服務工程 A/B(a-service、b-service)
-
項目啟動成功後訪問://localhost:8000/all/routeAll
-
首先會返回 ‘I’m Spring Cloud Gateway fallback.’,因為服務還未被註冊到註冊中心
-
然後會返回 ‘{“msg”:”缺少憑證”,”code”:-1}’,因為配置了全局過濾器,如下
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;
/**
* @ClassName TokenFilter
* @Desc TODO 請求認證過濾器
* @Date 2019/6/29 17:49
* @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");
}));
}
}
-
全局過濾器,不需要配置在配置文件中,作用於所有路由;只是這裡在處理前做了判斷,只有路徑中存在routeAll 字元串才到後續處理;並且處理分為請求前的處理,和響應後的處理
-
此時在地址://localhost:8000/all/routeAll 中添加 token 參數
-
輪流輸出內容:’Can I pass? yes! port:9000′ 和 ‘Can I pass? yes! port:9001’
-
觀察 gateway 工程的控制台,會有如下內容輸出
響應碼:null,請求路徑:/routeAll
filter -> before
響應碼:200,請求路徑:/routeAll
filter -> after
13. 證明全局過濾器過濾成功
service 工程 – 項目結構
把多工程項目使用 IntelliJ IDEA 打開
1.把項目從 GitHub 中下載到你的本地
2.打開 IntelliJ IDEA
3.點擊 File -> Open
4.打開你下載到本地的項目目錄
5.springcloud-gateway -> springcloud-gateway-service(選擇打開此工程)
6.打開 service 工程後
7.再次點擊 File -> Project Structrue
8.選擇 Modules,點擊 ‘+’ 符號
9.點擊 Import Module
10.還是打開你下載到本地的項目目錄
11.springcloud-gateway -> springcloud-gateway-commons -> pom.xml
12.點擊 OK
13.點擊 Next,Finish
14.點擊 Apply,OK