Spring Cloud Gateway简介
Spring Cloud Gateway是spring官方替代zuul作为网关的解决方案.
Spring Cloud Gateway requires the Netty runtime provided by Spring Boot and Spring Webflux.
基于Spring Boot 2.X 和 Spring Webflux,不能在Servlet容器中运行,采用非阻塞API,相比zuul,优化了很多配置。
相关词汇
- Route: 路由网关构建过滤规则,由id,目标url,Predicate规则,Filter定义,如果Predicate的结果为true,则匹配到路由。
- Predicate: Java 8 Function Predicate,它可以接受输入参数,返回一个布尔值结果,靠它匹配请求的path,headers ,参数。
- Filter: 路由过程中的filter,分为 GlobalFilter(全局过滤器) ,GatewayFilter。
工作流程
这是官方文档中的流程,client 向 gateway 发送请求,首先在 Gateway Handler Mapping 中匹配路由,如果匹配到就将请求传递到对应的 Handler ,Handler再执行设置的过滤器链,最后将请求发送到代理的服务。
内置Predicate
- 时间: 包括 After,Before ,Between 匹配请求时间
- Cookie: 提供了匹配请求Cookie名和正则表达式的功能
- Header:提供了匹配请求Header名和正则表达式的功能
- Host:匹配主机名,支持 URI 模板,例如 {sub}.myhost.org
- Method:匹配请求方法
- Path:匹配请求路径
- Query:匹配请求参数
- RemoteAddr:匹配ip地址和子网掩码
过滤器
- AddRequestHeader:转发请求前增加Header
- AddRequestParameter:转发请求前增加参数
- AddResponseHeader:回调请求增加Header
- Hystrix:断路器
- FallbackHeaders:服务降级
- PrefixPath:为请求增加前缀
- PreserveHostHeader:发送原始Header
- RequestRateLimiter:限流,也可以通过Redis
- RedirectTo:重定向
- RemoveNonProxyHeaders:从转发的请求中删除Header
- RemoveRequestHeader:删除设置的Header
- RemoveResponseHeader:在响应返回到客户端之前删除Header
- RewritePath:通过正则表达式重写请求路径
- RewriteResponseHeader:通过正则表达式重写响应头值
- SaveSession:转发调用之前已保存会话状态
- SecureHeaders:增加安全Header
- SetPath:通过模板化路径段来操作请求路径
- SetResponseHeader:替换响应Header
- SetStatus:设置http status
- StripPrefix:转发请求前删除部分路径
- Retry: 重试
- RequestSize:限制请求大小
以上都是可以在application.yml中配置的内置过滤器,如果无法满足开发要求,可以自己在java DSL中配置。
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route("cos3", predicateSpec -> predicateSpec.path("/cos3/**")
.filters(gatewayFilterSpec -> {
gatewayFilterSpec.rewritePath("/cos3/(?<segment>.*)", "/$\\{segment}");
gatewayFilterSpec.filters(jwtFilter);
gatewayFilterSpec.preserveHostHeader();
gatewayFilterSpec.removeRequestHeader(HttpHeaders.AUTHORIZATION);
return gatewayFilterSpec;
})
.uri(cos3URI)
)
.build();
}
自定义过滤器
GlobalFilters
这种过滤器针对的是全局路由,还区分了 pre 和 post 两种阶段,确定代码是指在路由前执行还是路由后执行。
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter a() {
return (exchange, chain) -> {
log.info("pre");
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
log.info("post");
}));
};
}
GatewayFilter
这种过滤器针对的单独的路由,需要自己配置。
@Bean
public GatewayFilter sessionAuthenticationFilter() {
return (exchange, chain) -> {
String userMobile = exchange.getAttribute("User");
if (userMobile == null) {
log.info("session中不存在用户信息!");
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.FORBIDDEN);
return Mono.empty();
}
return chain.filter(exchange);
};
}
转发日志
在VM Options设置启动参数 -Dreactor.netty.http.server.accessLogEnabled=true
在logback.xml文件配置
<appender name="accessLog" class="ch.qos.logback.core.FileAppender">
<file>access_log.log</file>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<appender name="async" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="accessLog" />
</appender>
<logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false">
<appender-ref ref="async"/>
</logger>
网友评论