SpringCloud Gateway网关
在提供一种简单而有效的方式来路由到API,提供例如:安全性,监控指标等功能。
官方说明文档
//官方
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
Spring Cloud Gateway的工作方式:
三个重要部分
Route路由
网关的基本构建单元。它由ID,URI,匹配规则集合和过滤集合定义。
Predicate 判定器
判断请求走哪条路由规则。匹配来自HTTP请求的如何内容,例如标头或者参数。
Filter 过滤器
用于在发送下游请求之前或之后修改请求和响应
内置路由选择器
Route Predicate Factories
路由选择器 | 描述 |
---|---|
After | 匹配在指定日期之后发生的请求 |
Before | 匹配在指定日期时间之前发生的请求 |
Between | 匹配在指定日期时间之间发生的请求 |
Cookie | 匹配具有指定Cookie值的请求 |
Header | 匹配header中具有指定名称且值与正则表达式匹配的请求 |
Host | 匹配指定的host |
Method | 匹配指定的method |
Path | 匹配指定的请求路径 |
Query | 匹配指定的查询参数 |
RemoteAddr | 匹配指定的客户端ip |
内置过滤器
GatewayFilter Factories
过滤器类型 | 描述 |
---|---|
AddRequestHeader | 网关下游请求发起前,增加请求的header |
AddRequestParameter | 网关下游请求发起前,增加请求的参数 |
AddResponseHeader | 网关下游响应之后,增加响应的header |
Hystrix | 为该路由增加熔断器 |
FallbackHeaders | 熔断后,为响应增加一个降级的header |
PrefixPath | 设置发起网关下游请求的路径前缀(隐藏真实路径) |
PreserveHostheader | 网关发起下游请求时,是否在header中附带原请求中的host |
RequestRateLimiter | 网关限流器(可选择结合redis实现) |
RedirectTo | 将该路由的请求重定向到指定地址 |
RemoveNoProxyHeaders | 网关发起下游请求时,删除指定header(默认删除一系列header名) |
RemoveRequestHeader | 网关下游请求发起前,删除指定的请求header |
RemoveResponseHeader | 网关下游响应之后,删除指定的响应的header |
RewritePath | 请求路径重写 |
RewriteResponseHeader | 重写指定的响应header |
SaveSession | 网关保存session会话 |
SecureHeaders | 为响应内容增加一系列和安全相关的header信息 |
SetPath | 路径修改(重写类型) |
SetResponseheader | 替换(不是新增)指定的响应header |
SetStatus | 设置该路由的响应状态码 |
StripPrefix | 网关在发起请求之前,根据/分隔删除部分url路径(eg:2,则/name/bar/foo变为/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 | 要添加过滤器并将其应用于所有路由 |
全局过滤器
GlobalFilter
//官网示例
@Bean
public GlobalFilter customFilter() {
return new CustomGlobalFilter();
}
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono 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 {
/**
* 定义可以再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 filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.err.println("GatewayFilter config 自定义过滤器工厂 filter==");
return chain.filter(exchange);
}
};
}
@Override
public List 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
集成示例
1 . pom导入依赖
1.8
Hoxton.SR9
org.springframework.cloud
spring-cloud-starter-gateway
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
配置
@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 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 {
/**
* 定义可以再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 filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// System.err.println("GatewayFilter config 自定义过滤器工厂 filter==");
// return chain.filter(exchange);
// }
// };
return new InnerFilter(config);
}
@Override
public List shortcutFieldOrder() {
return Arrays.asList(TYPE, TYPE_2);
}
/**
* 设置 执行顺序
*/
public class InnerFilter implements GatewayFilter, Ordered {
private Config config;
public InnerFilter(Config config){
this.config = config;
}
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//按order,优先被执行,CustomGlobalFilter执行,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() {
//数字越小,优先级越高
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
执行顺序