SpringCloud Gateway網關
在提供一種簡單而有效的方式來路由到API塑悼,提供例如:安全性摘悴,監(jiān)控指標等功能稚铣。
官方說明文檔
//官方
https://spring.io/projects/spring-cloud-gateway#overview
//官方說明文檔
https://docs.spring.io/spring-cloud-gateway/docs/2.2.5.RELEASE/reference/html/index.html#gateway-starter
image.png
image.png
Spring Cloud Gateway的工作方式:
官網截圖.png
三個重要部分
Route路由
網關的基本構建單元是整。它由ID,URI拭嫁,匹配規(guī)則集合和過濾集合定義可免。
Predicate 判定器
判斷請求走哪條路由規(guī)則。匹配來自HTTP請求的如何內容做粤,例如標頭或者參數浇借。
Filter 過濾器
用于在發(fā)送下游請求之前或之后修改請求和響應
內置路由選擇器
Route Predicate Factories
路由選擇器 | 描述 |
---|---|
After | 匹配在指定日期之后發(fā)生的請求 |
Before | 匹配在指定日期時間之前發(fā)生的請求 |
Between | 匹配在指定日期時間之間發(fā)生的請求 |
Cookie | 匹配具有指定Cookie值的請求 |
Header | 匹配header中具有指定名稱且值與正則表達式匹配的請求 |
Host | 匹配指定的host |
Method | 匹配指定的method |
Path | 匹配指定的請求路徑 |
Query | 匹配指定的查詢參數 |
RemoteAddr | 匹配指定的客戶端ip |
image.png
內置過濾器
GatewayFilter Factories
過濾器類型 | 描述 |
---|---|
AddRequestHeader | 網關下游請求發(fā)起前,增加請求的header |
AddRequestParameter | 網關下游請求發(fā)起前怕品,增加請求的參數 |
AddResponseHeader | 網關下游響應之后妇垢,增加響應的header |
Hystrix | 為該路由增加熔斷器 |
FallbackHeaders | 熔斷后,為響應增加一個降級的header |
PrefixPath | 設置發(fā)起網關下游請求的路徑前綴(隱藏真實路徑) |
PreserveHostheader | 網關發(fā)起下游請求時,是否在header中附帶原請求中的host |
RequestRateLimiter | 網關限流器(可選擇結合redis實現(xiàn)) |
RedirectTo | 將該路由的請求重定向到指定地址 |
RemoveNoProxyHeaders | 網關發(fā)起下游請求時修己,刪除指定header(默認刪除一系列header名) |
RemoveRequestHeader | 網關下游請求發(fā)起前恢总,刪除指定的請求header |
RemoveResponseHeader | 網關下游響應之后,刪除指定的響應的header |
RewritePath | 請求路徑重寫 |
RewriteResponseHeader | 重寫指定的響應header |
SaveSession | 網關保存session會話 |
SecureHeaders | 為響應內容增加一系列和安全相關的header信息 |
SetPath | 路徑修改(重寫類型) |
SetResponseheader | 替換(不是新增)指定的響應header |
SetStatus | 設置該路由的響應狀態(tài)碼 |
StripPrefix | 網關在發(fā)起請求之前睬愤,根據/分隔刪除部分url路徑(eg:2,則/name/bar/foo變?yōu)?foo) |
Retry | 為指定路由開啟錯誤重試機制 |
RequestSize | 請求內容大小限制纹安,超出大小則返回413Payload Too Large |
Modify Request Body | 網關修改客戶端的請求內容尤辱,僅支持代碼設置(實質性功能) |
Modify Response Body | 網關修改下游的響應內容,僅支持代碼設置(實質性功能) |
LoadBalancerClient | 自定義路由的負載均衡(配置ribbon服務后厢岂,路由的uri修改為lb:service)(eureka無關) |
Websocket | 支持websocket代理(配置方式uri:ws://localhost:3001) |
Gateway Metrics Filter | 開啟路由metrics功能(spring.cloud.gateway.metrics.enabled=true默認false關閉) |
default filters | 要添加過濾器并將其應用于所有路由 |
image.png
全局過濾器
GlobalFilter
//官網示例
@Bean
public GlobalFilter customFilter() {
return new CustomGlobalFilter();
}
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("custom global filter");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1;
}
}
局部過濾器
GatewayFilter
@Configuration
public class GatewayFilterConfig {
// /**
// * 把過濾器注入容器
// * @return
// */
@Bean
TestGatewayFilterFactory testGatewayFilterFactory(){
return new TestGatewayFilterFactory();
}
}
/**
* 局部過濾器
*
*/
public class TestGatewayFilterFactory extends AbstractGatewayFilterFactory<TestGatewayFilterFactory.Config> {
/**
* 定義可以再yaml中聲明的屬性變量
*/
private static final String TYPE = "type";//參數
private static final String TYPE_2 = "type_2";//參數2
public TestGatewayFilterFactory(){
//這里需要將自定義的config傳過去光督,否則會報告ClassCastException
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
System.err.println("GatewayFilter config 自定義過濾器工廠,config="+config.toString());
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.err.println("GatewayFilter config 自定義過濾器工廠 filter==");
return chain.filter(exchange);
}
};
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(TYPE, TYPE_2);
}
//自定義的config類,用來設置傳入的參數
public static class Config{
//Put the configuration properties for your filter here
/**
* 過濾類型
*/
private String type;
/**
* 操作
*/
private String type_2;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getType_2() {
return type_2;
}
public void setType_2(String type_2) {
this.type_2 = type_2;
}
@Override
public String toString() {
return "Config{" +
"type='" + type + '\'' +
", type_2='" + type_2 + '\'' +
'}';
}
}
}
在application.yml配置文件,配置自定義filters
spring:
application:
name: spring-cloud-gateway
cloud:
gateway:
# 路由 id
routes:
- id: study
# 注冊服務的名: lb://
uri: lb://server-demo
predicates: #斷言
- Path=/index/**
# - Query=paramA
# - Before=2020-04-20T06:06:06+08:00[Asia/Shanghai]
filters:
- name: Test
args:
type: root
type_2: 1112233333
image.png
集成示例
1 . pom導入依賴
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>
<dependencies>
<!--gateway 包含了web-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--netflix-eureka-client注冊中心客戶端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
配置
@Configuration
public class GatewayFilterConfig {
// /**
// * 把過濾器注入容器
// * @return
// */
@Bean
TestGatewayFilterFactory testGatewayFilterFactory(){
return new TestGatewayFilterFactory();
}
/**
* 全局過濾鏈
* @return
*/
@Bean
public GlobalFilter customFilter() {
return new CustomGlobalFilter();
}
/**
* 全局攔截
* 全局過濾器GlobalFilter
*/
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.err.println("GlobalFilter CustomGlobalFilter ");
return chain.filter(exchange);
}
/**
* 攔截順序
* @return
*/
@Override
public int getOrder() {
return -1;
}
}
}
TestGatewayFilterFactory 局部過濾器
/**
* 局部過濾器
*
*/
public class TestGatewayFilterFactory extends AbstractGatewayFilterFactory<TestGatewayFilterFactory.Config> {
/**
* 定義可以再yaml中聲明的屬性變量
*/
private static final String TYPE = "type";//參數
private static final String TYPE_2 = "type_2";//參數2
public TestGatewayFilterFactory(){
//這里需要將自定義的config傳過去塔粒,否則會報告ClassCastException
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
System.err.println("GatewayFilter config 自定義過濾器工廠,config="+config.toString());
// return new GatewayFilter() {
// @Override
// public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// System.err.println("GatewayFilter config 自定義過濾器工廠 filter==");
// return chain.filter(exchange);
// }
// };
return new InnerFilter(config);
}
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList(TYPE, TYPE_2);
}
/**
* 設置 執(zhí)行順序
*/
public class InnerFilter implements GatewayFilter, Ordered {
private Config config;
public InnerFilter(Config config){
this.config = config;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//按order结借,優(yōu)先被執(zhí)行,CustomGlobalFilter執(zhí)行卒茬,apply(),then方法
System.err.println("GatewayFilter config 自定義過濾器工廠 InnerFilter 船老,config="+this.config.toString());
//進入下一個處理流程
// return chain.filter(exchange);
// 在then方法里的,相當于aop中的后置通知
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
System.out.println(" post 自定義過濾器工廠 AAAA " + this.getClass().getSimpleName());
}));
}
@Override
public int getOrder() {
//數字越小圃酵,優(yōu)先級越高
return -100;
}
}
//自定義的config類柳畔,用來設置傳入的參數
public static class Config{
//Put the configuration properties for your filter here
/**
* 過濾類型
*/
private String type;
/**
* 操作
*/
private String type_2;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getType_2() {
return type_2;
}
public void setType_2(String type_2) {
this.type_2 = type_2;
}
@Override
public String toString() {
return "Config{" +
"type='" + type + '\'' +
", type_2='" + type_2 + '\'' +
'}';
}
}
}
application配置
server:
port: 8090
spring:
application:
name: spring-cloud-gateway
cloud:
gateway:
# 路由 id
routes:
- id: study
# 注冊服務的名: lb://
uri: lb://server-demo
predicates: #斷言
- Path=/index/**
# - Query=paramA
# - Before=2020-04-20T06:06:06+08:00[Asia/Shanghai]
filters:
- name: Test
args:
type: root
type_2: 1112233333
# 自定義 filters
discovery:
locator:
enabled: true
enabled: true
httpclient:
ssl:
handshake-timeout: 10000
close-notify-flush-timeout: 3000
close-notify-read-timeout: 0
use-insecure-trust-manager: true
# eureka
eureka:
client:
enabled: true
service-url: # http://localhost:8761/eureka/
defaultZone: http://localhost:8761/eureka/
register-with-eureka: true
fetch-registry: true
#
logging:
level:
# root: debug
org.springframework.cloud: debug
執(zhí)行順序
image.png