Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0、Spring Boot 2.0 和 Project Reactor 等技术开发的网关,Spring Cloud Gateway 旨在为微服务架构提供一种简单有效的、统一的 API 路由管理方式。
Spring Cloud Gateway 作为 Spring Cloud 生态系中的网关,其目标是替代 Netflix Zuul,它不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全、监控/埋点和限流等。
Spring Cloud Gateway 依赖 Spring Boot 和 Spring WebFlux,基于 Netty 运行。它不能在传统的 servlet 容器中工作,也不能构建成 war 包。
Route 是网关的基础元素,它由唯一标识(ID)、目标服务地址(uri)、一组断言(predicates)和一组过滤器组成(filters)。filters 不是必需参数。
下面是配置类中的
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
这条请求匹配在一定日期之后发生的任何请求
如果把上面的after改成before就变成了 在一定日期之前发生的任何请求
如果把上面的after改成between,并且添加一个日期,就变成了 在俩日期之间发生的任何请求
Path-route 断言工厂
spring:
cloud:
gateway:
routes:
- id: atf-ms
# 目标服务地址(uri:地址,请求转发后的地址)
uri: lb://atf-ms
# 路由条件(predicates:断言,匹配 HTTP 请求内容)
predicates:
## 转发地址格式为 uri/archive
- Path=/atf-ms/**
filters:
- StripPrefix=1
- name: CusHystrix
args:
name: default
fallbackUri: forward:/defaultfallback
这里的请求路径是 http://localhost:8002/atf-ms/user/users/2 下面必须加上 StripPrefix=1 否则访问的时候回带上atf-ms
spring:
cloud:
gateway:
default-filters:
- TokenValidate
routes:
...
此处是配置是全局过滤器了,是所有的route都会经过这个,也可以直接配置到某个路由上。
客户端向 Spring Cloud Gateway 发出请求,如果请求与网关程序定义的路由匹配,则该请求就会被发送到网关 Web 处理程序,此时处理程序运行特定的请求过滤器链。 过滤器
过滤器分为两种
- GlobalFilter : 全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器
- GatewayFilter : 需要通过spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过spring.cloud.default-filters配置在全局,作用在所有路由上
/**
* 自定义一个全局过滤器
* 实现 globalfilter , ordered接口
*/
@Component
public class LoginFilter implements GlobalFilter,Ordered {
//这个方法是调用链前后 返回值越大越后执行
@Override
public int getOrder() {
// -1 是 response write filter,当前filter必须在此之前调用
return Ordered.HIGHEST_PRECEDENCE + 3;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("执行了自定义的全局过滤器");
//1.获取请求参数access-token
String token = exchange.getRequest().getQueryParams().getFirst("access-token");
//2.判断是否存在
if(token == null) {
//3.如果不存在 : 认证失败
System.out.println("没有登录");
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete(); //请求结束
}
//4.如果存在,继续执行
return chain.filter(exchange); //继续向下执行
}
}
ServerWebExchange 类解析
public interface ServerWebExchange {
// 日志前缀属性的KEY,值为org.springframework.web.server.ServerWebExchange.LOG_ID
// 可以理解为 attributes.set("org.springframework.web.server.ServerWebExchange.LOG_ID","日志前缀的具体值");
// 作用是打印日志的时候会拼接这个KEY对饮的前缀值,默认值为""
String LOG_ID_ATTRIBUTE = ServerWebExchange.class.getName() + ".LOG_ID";
String getLogPrefix();
// 获取ServerHttpRequest对象
ServerHttpRequest getRequest();
// 获取ServerHttpResponse对象
ServerHttpResponse getResponse();
// 返回当前exchange的请求属性,返回结果是一个可变的Map
Map<String, Object> getAttributes();
// 根据KEY获取请求属性
@Nullable
default <T> T getAttribute(String name) {
return (T) getAttributes().get(name);
}
// 根据KEY获取请求属性,做了非空判断
@SuppressWarnings("unchecked")
default <T> T getRequiredAttribute(String name) {
T value = getAttribute(name);
Assert.notNull(value, () -> "Required attribute '" + name + "' is missing");
return value;
}
// 根据KEY获取请求属性,需要提供默认值
@SuppressWarnings("unchecked")
default <T> T getAttributeOrDefault(String name, T defaultValue) {
return (T) getAttributes().getOrDefault(name, defaultValue);
}
// 返回当前请求的网络会话
Mono<WebSession> getSession();
// 返回当前请求的认证用户,如果存在的话
<T extends Principal> Mono<T> getPrincipal();
// 返回请求的表单数据或者一个空的Map,只有Content-Type为application/x-www-form-urlencoded的时候这个方法才会返回一个非空的Map -- 这个一般是表单数据提交用到
Mono<MultiValueMap<String, String>> getFormData();
// 返回multipart请求的part数据或者一个空的Map,只有Content-Type为multipart/form-data的时候这个方法才会返回一个非空的Map -- 这个一般是文件上传用到
Mono<MultiValueMap<String, Part>> getMultipartData();
// 返回Spring的上下文
@Nullable
ApplicationContext getApplicationContext();
// 这几个方法和lastModified属性相关
boolean isNotModified();
boolean checkNotModified(Instant lastModified);
boolean checkNotModified(String etag);
boolean checkNotModified(@Nullable String etag, Instant lastModified);
// URL转换
String transformUrl(String url);
// URL转换映射
void addUrlTransformer(Function<String, String> transformer);
// 注意这个方法,方法名是:改变,这个是修改ServerWebExchange属性的方法,返回的是一个Builder实例,Builder是ServerWebExchange的内部类
default Builder mutate() {
return new DefaultServerWebExchangeBuilder(this);
}
interface Builder {
// 覆盖ServerHttpRequest
Builder request(Consumer<ServerHttpRequest.Builder> requestBuilderConsumer);
Builder request(ServerHttpRequest request);
// 覆盖ServerHttpResponse
Builder response(ServerHttpResponse response);
// 覆盖当前请求的认证用户
Builder principal(Mono<Principal> principalMono);
// 构建新的ServerWebExchange实例
ServerWebExchange build();
}
}
GatewayFilterChain 类 解析
/**
* 网关过滤链表接口
* 用于过滤器的链式调用
* Contract to allow a {@link WebFilter} to delegate to the next in the chain.
* * @author Rossen Stoyanchev
* @since 5.0
*/
public interface GatewayFilterChain {
/**
* 链表启动调用入口方法
* Delegate to the next {@code WebFilter} in the chain.
* @param exchange the current server exchange
* @return {@code Mono} to indicate when request handling is complete
*/
Mono<Void> filter(ServerWebExchange exchange);
}
过滤器的GatewayFilterChain 执行顺序
参考文章 http://c.biancheng.net/view/5434.html