- 1 使用
- 2 概念
- 3 工作机制
- 4 配置路由
- 5 路由断言
- 5.6 HostRoutePredicateFactory
- 5.7 MethodRoutePredicateFactory
- 5.8 PathRoutePredicateFactory
- 5.9 QueryRoutePredicateFactory
- 5.10 RemoteAddrRoutePredicateFactory
- 5.11 WeightRoutePredicateFactory
- 5.12 ReadBodyRoutePredicateFactory
- 5.13 CloudFoundryRouteServiceRoutePredicateFactory
- 6 路由过滤
- 6.1 AddRequestHeaderGatewayFilterFactory
- 6.2 AddRequestParameterGatewayFilterFactory
- 6.3 AddResponseHeaderGatewayFilterFactory
- 6.4 DedupeResponseHeaderGatewayFilterFactory
- 6.5 FallbackHeadersGatewayFilterFactory
- 6.6 HystrixGatewayFilterFactory
- 6.7 MapRequestHeaderGatewayFilterFactory
- 6.8 PrefixPathGatewayFilterFactory
- 6.9 PreserveHostHeaderGatewayFilterFactory
- 6.10 RedirectToGatewayFilterFactory
- 6.11 RemoveRequestHeaderGatewayFilterFactory
- 6.12 RemoveRequestParameterGatewayFilterFactory
- 6.13 RemoveResponseHeaderGatewayFilterFactory
- 6.14 RequestHeaderSizeGatewayFilterFactory
- 6.15 RequestHeaderToRequestUriGatewayFilterFactory
- 6.16 RequestRateLimiterGatewayFilterFactory
- 6.17 RequestSizeGatewayFilterFactory
- 6.18 RetryGatewayFilterFactory
- 6.19 RewriteLocationResponseHeaderGatewayFilterFactory
- 6.20 RewritePathGatewayFilterFactory
- 6.21 SaveSessionGatewayFilterFactory
- 6.22 SecureHeadersGatewayFilterFactory
- 6.23 SetPathGatewayFilterFactory
- 6.24 SetResponseHeaderGatewayFilterFactory
- 6.25 SetRequestHeaderGatewayFilterFactory
- 6.26 SetStatusGatewayFilterFactory
- 6.27 SpringCloudCircuitBreakerFilterFactory
- 6.28 SpringCloudCircuitBreakerHystrixFilterFactory
- 6.29 SpringCloudCircuitBreakerResilience4JFilterFactory
- 6.30 StripPrefixGatewayFilterFactory
- 7 全局过滤器
- 8 Http请求头过滤器
- 9 TLS SSL
- 10 配置
- 11 路由元数据配置
- 12 HTTP超时设置
- 13 Netty请求方位日志
- 14 跨域设置
- 15 监控
- 16 故障排除
- 17 开发者指南
1 使用
- 组件
- Spring 5
- Spring Boot 2
- Spring WebFlux
- Netty
- 功能
- 鉴权授权
- 系统监控
- 反向代理
- 流量控制
- 日志管理
- 安全管理
- 协议转换
- 服务注册
- 服务发现
- 业务缓存
- 业务隔离
Spring Cloud Gateway 需要 Spring Boot 和 Spring Webflux 提供的 Netty 运行时。它不能在传统的Servlet 容器中工作,也不能构建成WAR包运行。
# 打开网关功能
spring.cloud.gateway.enabled=true
# 添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2 概念
Route(路由):路由是构建网关的基本模块,它由 ID、目标 URI、一系列的断言和过滤器组成,如果断言为 true 则匹配该路由。
Predicate(断言):参考的是 Java8 中的 java.util.function.Predicate。开发人员可以匹配 HTTP 请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由。
Filter(路由):框架提供的GatewayFilter,可以在请求被路由之前或之后对请求进行修改。
3 工作机制
客户端向网关发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关 Web 处理程序。该处理程序通过特定于请求的过滤器链来运行请求。用虚线划分过滤器的原因是,过滤器可以在发送代理请求之前和之后运行逻辑。执行所有“前置”过滤器逻辑。然后发出代理请求。发出代理请求后,将运行“后置”过滤器逻辑。
4 配置路由
4.2 配置文件
# 静态路由
spring.cloud.gateway.routes[0].id=route-sina
spring.cloud.gateway.routes[0].uri=https://www.sina.com.cn/
spring.cloud.gateway.routes[0].predicates[0]=Path=/sina/**
spring.cloud.gateway.routes[0].order=1
# 动态路由
spring.cloud.gateway.routes[1].id=route-service-name
spring.cloud.gateway.routes[1].uri=lb:/micro-service-name 服务实例
spring.cloud.gateway.routes[1].predicates[0]=Path=/name/**
spring.cloud.gateway.routes[1].order=1
4.2 代码配置
@Configuration
public class RouteConfig {
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes().
route("route-cnblogs", r -> r.path("/cnblogs/**")
.uri("https://www.cnblogs.com/")
.order(1))
.build();
}
}
5 路由断言
5.1 AfterRoutePredicateFactory
5.1.1 配置
spring.cloud.gateway.routes[0].predicates[1]=
After=2021-12-24T14:19:43.863+08:00[Asia/Shanghai]
5.1.2 关键代码
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange serverWebExchange) {
final ZonedDateTime now = ZonedDateTime.now();
return now.isAfter(config.getDatetime());
}
}
5.2 BeforeRoutePredicateFactory
5.2.1 配置
spring.cloud.gateway.routes[0].predicates[2]=
Before=2021-12-24T14:19:43.863+08:00[Asia/Shanghai]
5.2.2 关键代码
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange serverWebExchange) {
final ZonedDateTime now = ZonedDateTime.now();
return now.isBefore(config.getDatetime());
}
}
5.3 BetweenRoutePredicateFactory
5.3.1 配置
spring.cloud.gateway.routes[0].predicates[3]=
Between=2021-12-24T14:19:43.863+08:00[Asia/Shanghai],2021-12-24T14:28:43.863+08:00[Asia/Shanghai]
5.3.2 关键代码
public Predicate<ServerWebExchange> apply(Config config) {
Assert.isTrue(config.getDatetime1().isBefore(config.getDatetime2()),
config.getDatetime1() + " must be before " + config.getDatetime2());
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange serverWebExchange) {
final ZonedDateTime now = ZonedDateTime.now();
return now.isAfter(config.getDatetime1())
&& now.isBefore(config.getDatetime2());
}
}
5.4 CookieRoutePredicateFactory
Cookie 路由断言工厂接受两个参数,Cookie 名称和 regexp (一个 Java 正则表达式)。该谓词匹配具有给定名称且其值与正则表达式匹配的 cookie。
5.4.1 配置
spring.cloud.gateway.routes[0].predicates[2]=Cookie=auth-token,^1{n}$
5.4.2 关键代码
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
List<HttpCookie> cookies = exchange.getRequest().getCookies()
.get(config.name);
if (cookies == null) {
return false;
}
for (HttpCookie cookie : cookies) {
if (cookie.getValue().matches(config.regexp)) {
return true;
}
}
return false;
}
}
5.5 HeaderRoutePredicateFactory
Header 路由断言工厂接受两个参数: Header名称和 regexp (一个 Java 正则表达式)。与具有给定名称的请求头匹配,该请求头的值与正则表达式匹配。
5.5.1 配置
spring.cloud.gateway.routes[0].predicates[2]=Header=auth-token,[a-h]{6}
5.5.2 关键代码
@Override
public Predicate<ServerWebExchange> apply(Config config) {
boolean hasRegex = !StringUtils.isEmpty(config.regexp);
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
List<String> values = exchange.getRequest().getHeaders()
.getOrDefault(config.header, Collections.emptyList());
if (values.isEmpty()) {
return false;
}
// values is now guaranteed to not be empty
if (hasRegex) {
// check if a header value matches
return values.stream()
.anyMatch(value -> value.matches(config.regexp));
}
return true;
}
};
}
5.6 HostRoutePredicateFactory
Host 路由断言工厂接受一个参数: 主机名列表。支持Ant分割模式,匹配Host请求头。
5.6.1 配置
spring.cloud.gateway.routes[0].predicates[3]=Host=127.0.0.1:9010,**.evan.com
5.6.2 关键diamante
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
String host = exchange.getRequest().getHeaders().getFirst("Host");
Optional<String> optionalPattern = config.getPatterns().stream()
.filter(pattern -> pathMatcher.match(pattern, host)).findFirst();
if (optionalPattern.isPresent()) {
Map<String, String> variables = pathMatcher
.extractUriTemplateVariables(optionalPattern.get(), host);
ServerWebExchangeUtils.putUriTemplateVariables(exchange, variables);
return true;
}
return false;
}
};
}
5.7 MethodRoutePredicateFactory
Method 路由断言工厂接受一个参数: 支持的请求方式,多个方式逗号隔开
5.7.1 配置
spring.cloud.gateway.routes[0].predicates[4]=Method=GET,POST
5.7.2 关键代码
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
HttpMethod requestMethod = exchange.getRequest().getMethod();
return stream(config.getMethods())
.anyMatch(httpMethod -> httpMethod == requestMethod);
}
};
}
5.8 PathRoutePredicateFactory
5.8.1 配置
spring.cloud.gateway.routes[0].predicates[0]=Path=/sina/**
5.8.2 关键代码
org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory
5.9 QueryRoutePredicateFactory
Query 路由断言工厂接受两个参数: 请求参数和一个可选的regexp表达式
5.9.1 配置
spring.cloud.gateway.routes[0].predicates[5]=Query=name,xiao[1-9]
5.9.2 关键代码
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return new GatewayPredicate() {
@Override
public boolean test(ServerWebExchange exchange) {
if (!StringUtils.hasText(config.regexp)) {
// check existence of header
return exchange.getRequest().getQueryParams()
.containsKey(config.param);
}
List<String> values = exchange.getRequest().getQueryParams()
.get(config.param);
if (values == null) {
return false;
}
for (String value : values) {
if (value != null && value.matches(config.regexp)) {
return true;
}
}
return false;
}
};
}
5.10 RemoteAddrRoutePredicateFactory
5.10.1 配置
spring.cloud.gateway.routes[0].predicates[6]=RemoteAddr=192.168.1.1/24
5.10.2 关键代码
5.11 WeightRoutePredicateFactory
5.12 ReadBodyRoutePredicateFactory
5.13 CloudFoundryRouteServiceRoutePredicateFactory
6 路由过滤
6.1 AddRequestHeaderGatewayFilterFactory
添加请求头
AddRequestHeader=X-Request-red, blue
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
String value = ServerWebExchangeUtils.expand(exchange, config.getValue());
ServerHttpRequest request = exchange.getRequest().mutate()
.header(config.getName(), value).build();
return chain.filter(exchange.mutate().request(request).build());
}
};
}
6.2 AddRequestParameterGatewayFilterFactory
添加请求Query参数
AddRequestParameter=red, blue
6.3 AddResponseHeaderGatewayFilterFactory
添加响应头
AddResponseHeader=X-Response-Red, Blue
@Override
public GatewayFilter apply(NameValueConfig config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
String value = ServerWebExchangeUtils.expand(exchange, config.getValue());
exchange.getResponse().getHeaders().add(config.getName(), value);
return chain.filter(exchange);
}
};
}
6.4 DedupeResponseHeaderGatewayFilterFactory
去除重复的响应头
DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
6.5 FallbackHeadersGatewayFilterFactory
6.6 HystrixGatewayFilterFactory
6.7 MapRequestHeaderGatewayFilterFactory
请求头重命名
MapRequestHeader=Blue, X-Request-Red
@Override
public GatewayFilter apply(MapRequestHeaderGatewayFilterFactory.Config config) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
if (!exchange.getRequest().getHeaders()
.containsKey(config.getFromHeader())) {
return chain.filter(exchange);
}
List<String> headerValues = exchange.getRequest().getHeaders()
.get(config.getFromHeader());
ServerHttpRequest request = exchange.getRequest().mutate()
.headers(i -> i.addAll(config.getToHeader(), headerValues))
.build();
return chain.filter(exchange.mutate().request(request).build());
}
};
}
6.8 PrefixPathGatewayFilterFactory
6.9 PreserveHostHeaderGatewayFilterFactory
6.10 RedirectToGatewayFilterFactory
RedirectTo=302, https://acme.org
public GatewayFilter apply(String statusString, String urlString) {
HttpStatusHolder httpStatus = HttpStatusHolder.parse(statusString);
Assert.isTrue(httpStatus.is3xxRedirection(),
"status must be a 3xx code, but was " + statusString);
final URI url = URI.create(urlString);
return apply(httpStatus, url);
}
public GatewayFilter apply(HttpStatusHolder httpStatus, URI uri) {
return new GatewayFilter() {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
if (!exchange.getResponse().isCommitted()) {
setResponseStatus(exchange, httpStatus);
final ServerHttpResponse response = exchange.getResponse();
response.getHeaders().set(HttpHeaders.LOCATION, uri.toString());
return response.setComplete();
}
return Mono.empty();
}
};
}
6.11 RemoveRequestHeaderGatewayFilterFactory
删除请求头
RemoveRequestHeader=X-Request-Foo
6.12 RemoveRequestParameterGatewayFilterFactory
删除请求参数
RemoveRequestParameter=red
6.13 RemoveResponseHeaderGatewayFilterFactory
删除响应头
RemoveResponseHeader=X-Response-Foo
6.14 RequestHeaderSizeGatewayFilterFactory
6.15 RequestHeaderToRequestUriGatewayFilterFactory
6.16 RequestRateLimiterGatewayFilterFactory
请求限流
6.17 RequestSizeGatewayFilterFactory
6.18 RetryGatewayFilterFactory
6.19 RewriteLocationResponseHeaderGatewayFilterFactory
6.20 RewritePathGatewayFilterFactory
重写请求路径
RewritePath=/red(?
6.21 SaveSessionGatewayFilterFactory
6.22 SecureHeadersGatewayFilterFactory
6.23 SetPathGatewayFilterFactory
6.24 SetResponseHeaderGatewayFilterFactory
6.25 SetRequestHeaderGatewayFilterFactory
6.26 SetStatusGatewayFilterFactory
6.27 SpringCloudCircuitBreakerFilterFactory
6.28 SpringCloudCircuitBreakerHystrixFilterFactory
6.29 SpringCloudCircuitBreakerResilience4JFilterFactory
6.30 StripPrefixGatewayFilterFactory
7 全局过滤器
7.1 GlobalFilter
@Configuration
public class GlobalFilterConfig {
@Bean
public FirstGlobalFilter firstGlobalFilter(){
return new FirstGlobalFilter();
}
}
public class FirstGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("pre FirstGlobalFilter");
return chain.filter(exchange).then(Mono.fromRunnable(new Runnable() {
@Override
public void run() {
log.info("post FirstGlobalFilter");
}
}));
}
@Override
public int getOrder() {
// 指定优先级
return 0;
}
}
7.2 ForwardRoutingFilter
服务内请求转发
forward的请求
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI requestUrl = (URI)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
String scheme = requestUrl.getScheme();
if (!ServerWebExchangeUtils.isAlreadyRouted(exchange) && "forward".equals(scheme)) {
if (log.isTraceEnabled()) {
log.trace("Forwarding to URI: " + requestUrl);
}
return this.getDispatcherHandler().handle(exchange);
} else {
return chain.filter(exchange);
}
}
7.3 LoadBalancerClientFilter
负载均衡
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);
if (url == null
|| (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
return chain.filter(exchange);
}
// preserve the original url
addOriginalRequestUrl(exchange, url);
// 选择策略实现类选择一个路由节点
final ServiceInstance instance = choose(exchange);
if (instance == null) {
throw NotFoundException.create(properties.isUse404(),
"Unable to find instance for " + url.getHost());
}
URI uri = exchange.getRequest().getURI();
// if the `lb:<scheme>` mechanism was used, use `<scheme>` as the default,
// if the loadbalancer doesn't provide one.
String overrideScheme = instance.isSecure() ? "https" : "http";
if (schemePrefix != null) {
overrideScheme = url.getScheme();
}
URI requestUrl = loadBalancer.reconstructURI(
new DelegatingServiceInstance(instance, overrideScheme), uri);
if (log.isTraceEnabled()) {
log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);
}
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
return chain.filter(exchange);
}
protected ServiceInstance choose(ServerWebExchange exchange) {
return loadBalancer.choose(
((URI) exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR)).getHost());
}
7.4 ReactiveLoadBalancerClientFilter
同上
Spring 官方提供的负责均衡过滤器
- spring.cloud.loadbalancer.ribbon.enabled 关闭ribbon负载均衡算法
增加依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-loadbalancer</artifactId> </dependency>
提供的负载均衡算法
- RoundRobinLoadBalancer 随机
-
7.5 NettyRoutingFilter
使用Netty的 HttpClient 转发http、https请求
7.6 NettyWriteResponseFilter
7.7 RouteToRequestUrlFilter
7.8 WebsocketRoutingFilter
Websocket路由网关过滤器。其根据ws://,wss://前缀(Scheme)过滤处理,代理后端Websocket服务,提供给客户端连接
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { changeSchemeIfIsWebSocketUpgrade(exchange); // 获取请求 URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR); String scheme = requestUrl.getScheme(); if (isAlreadyRouted(exchange) || (!"ws".equals(scheme) && !"wss".equals(scheme))) { return chain.filter(exchange); } // 设置请求已经被路由 setAlreadyRouted(exchange); HttpHeaders headers = exchange.getRequest().getHeaders(); HttpHeaders filtered = filterRequest(getHeadersFilters(), exchange); List<String> protocols = headers.get(SEC_WEBSOCKET_PROTOCOL); if (protocols != null) { protocols = headers.get(SEC_WEBSOCKET_PROTOCOL).stream().flatMap( header -> Arrays.stream(commaDelimitedListToStringArray(header))) .map(String::trim).collect(Collectors.toList()); } // 请求分发处理 return this.webSocketService.handleRequest(exchange, new ProxyWebSocketHandler( requestUrl, this.webSocketClient, filtered, protocols)); }
7.9 GatewayMetricsFilter
网关指标收集
spring.cloud.gateway.metrics.enabled=true
添加依赖<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { Sample sample = Timer.start(meterRegistry); return chain.filter(exchange) .doOnSuccess(aVoid -> endTimerRespectingCommit(exchange, sample)) .doOnError(throwable -> endTimerRespectingCommit(exchange, sample)); }
8 Http请求头过滤器
public interface HttpHeadersFilter { static HttpHeaders filterRequest(List<HttpHeadersFilter> filters, ServerWebExchange exchange) { HttpHeaders headers = exchange.getRequest().getHeaders(); return filter(filters, headers, exchange, Type.REQUEST); } static HttpHeaders filter(List<HttpHeadersFilter> filters, HttpHeaders input, ServerWebExchange exchange, Type type) { HttpHeaders response = input; if (filters != null) { HttpHeaders reduce = filters.stream() .filter(headersFilter -> headersFilter.supports(type)).reduce(input, (headers, filter) -> filter.filter(headers, exchange), (httpHeaders, httpHeaders2) -> { httpHeaders.addAll(httpHeaders2); return httpHeaders; }); return reduce; } return response; } /** * Filters a set of Http Headers. * @param input Http Headers * @param exchange a {@link ServerWebExchange} that should be filtered * @return filtered Http Headers */ HttpHeaders filter(HttpHeaders input, ServerWebExchange exchange); default boolean supports(Type type) { return type.equals(Type.REQUEST); } enum Type { REQUEST, RESPONSE } }
8.1 ForwardedHeadersFilter
8.2 RemoveHopByHopHeadersFilter
8.3 XForwardedHeadersFilter
增加X-Forwarded-For、X-Forwarded-Host、X-Forwarded-Port和X-Forwarded-Proto头部。代理转发时用以自定义的头部信息向下游传递。
9 TLS SSL
10 配置
10.1 核心类
路由信息定义 org.springframework.cloud.gateway.route.RouteDefinition
路由信息加载接口 org.springframework.cloud.gateway.route.RouteDefinitionLocator
配置
spring.cloud.gateway.routes[0].metadata.name=route-sina
获取数据
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR); route.getMetadata(); route.getMetadata(someKey);
12 HTTP超时设置
12.1 全局配置
spring.cloud.gateway.httpclient.connect-timeout=1000 spring.cloud.gateway.httpclient.response-timeout=5s
12.2 路由配置
spring.cloud.gateway.routes[0].metadata.connect-timeout=1000 spring.cloud.gateway.routes[0].metadata.response-timeout=5000
12.3 Fluent API
12.4 动态服务
spring.cloud.gateway.discovery.locator.enabled=true
DiscoveryClient 默认配置
/serviceId/
serviceId来自DiscoveryClient 的服务ID
13 Netty请求方位日志
开启Netty请求日志
-Dreactor.netty.http.server.accessLogEnabled=true
14 跨域设置
spring.cloud.gateway.globalcors.cors-configurations.[/**].allowedOrigins=https://docs.spring.io
spring.cloud.gateway.globalcors.cors-configurations.[/**].allowedMethods[0]=GET
15 监控
- 查看路由信息
- 查看全局过滤器
- 查看路由过滤器
- 刷新路由缓存
- 创建路由
16 故障排除
16.1 日志
logging.level.org.springframework.cloud.gateway=debug
logging.level.org.springframework.http.server.reactive=debug
logging.level.org.springframework.web.reactive=debug
logging.level.org.springframework.boot.autoconfigure.web=info
logging.level.reactor.netty=info
logging.level.redisratelimiter=info
16.2 请求日志
spring.cloud.gateway.httpserver.wiretap=true
spring.cloud.gateway.httpclient.wiretap=true
17 开发者指南
17.1 自定义RoutePredicateFactory
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<HeaderRoutePredicateFactory.Config> {
public MyRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
// grab configuration from Config object
return exchange -> {
//grab the request
ServerHttpRequest request = exchange.getRequest();
//take information from the request to see if it
//matches configuration.
return matches(config, request);
};
}
public static class Config {
//Put the configuration properties for your filter here
}
}
17.2 自定义GatewayFilterFactory
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<HeaderRoutePredicateFactory.Config> {
public MyRoutePredicateFactory() {
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
// grab configuration from Config object
return exchange -> {
//grab the request
ServerHttpRequest request = exchange.getRequest();
//take information from the request to see if it
//matches configuration.
return matches(config, request);
};
}
public static class Config {
//Put the configuration properties for your filter here
}
}
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {
public PostGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
// grab configuration from Config object
return (exchange, chain) -> {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
//Manipulate the response in some way
}));
};
}
public static class Config {
//Put the configuration properties for your filter here
}
}
17.3 自定义GlobalFilter
@Bean
public GlobalFilter customGlobalFilter() {
return (exchange, chain) -> exchange.getPrincipal()
.map(Principal::getName)
.defaultIfEmpty("Default User")
.map(userName -> {
//adds header to proxied request
exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build();
return exchange;
})
.flatMap(chain::filter);
}
@Bean
public GlobalFilter customGlobalPostFilter() {
return (exchange, chain) -> chain.filter(exchange)
.then(Mono.just(exchange))
.map(serverWebExchange -> {
//adds header to response
serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",
HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");
return serverWebExchange;
})
.then();
}