Spring Cloud Gateway简单入门,强大的微服务网关

我最新最全的文章都在 南瓜慢说 www.pkslow.com ,欢迎大家来喝茶!
1 简介 见名知义,Spring Cloud Gateway是用于微服务场景的网关组件,它是基于Spring WebFlux,也就是Reactive的。从实现原理上,它的性能应该是比Zuul会更好。
它的工作原理如下图所示:
Spring Cloud Gateway简单入门,强大的微服务网关
文章图片

简单而言就是通过一连串的Filter处理匹配到特定规则Predicates的请求。所以最主要就是做了两件事:
(1)哪些请求可以被它处理,由Predicates决定;
(2)如何处理,由Filters决定。
2 路由条件判断Predicates 2.1 时间匹配After 表示在什么时间之后才算满足条件匹配路由:
spring: cloud: gateway: routes: - id: after_route uri: https://example.org predicates: - After=2020-01-20T17:42:47.789-07:00[America/Denver]

2.2 时间匹配Before 表示在什么时间之前匹配路由:
spring: cloud: gateway: routes: - id: before_route uri: https://example.org predicates: - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

2.3 时间段匹配Between 表示在什么时间段匹配路由:
spring: cloud: gateway: routes: - id: between_route uri: https://example.org predicates: - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

2.4 Cookie匹配 表示通过判断Cookie的键值来匹配路由,其中值支持正则表达式:
spring: cloud: gateway: routes: - id: cookie_route uri: https://example.org predicates: - Cookie=chocolate, ch.p

2.5 请求头匹配Header 表示通过判断Http请求的Header来匹配路由:
spring: cloud: gateway: routes: - id: header_route uri: https://example.org predicates: - Header=X-Request-Id, \d+

2.6 主机名匹配Host 通过判断Hostname来匹配路由:
spring: cloud: gateway: routes: - id: host_route uri: https://example.org predicates: - Host=**.somehost.org,**.anotherhost.org

2.7 请求方法匹配Method 表示通过判断请求方法来匹配路由:
spring: cloud: gateway: routes: - id: method_route uri: https://example.org predicates: - Method=GET,POST

2.8 请求路径匹配Path 表示通过判断请求路径来匹配路由,很常用:
spring: cloud: gateway: routes: - id: path_route uri: https://example.org predicates: - Path=/red/{segment},/blue/{segment}

2.9 请求参数匹配Query 表示通过判断请求参数来匹配路由:
spring: cloud: gateway: routes: - id: query_route uri: https://example.org predicates: - Query=red, gree.

2.10 IP地址匹配RemoteAddr 表示通过判断IP地址来匹配路由:
spring: cloud: gateway: routes: - id: remoteaddr_route uri: https://example.org predicates: - RemoteAddr=192.168.1.1/24

2.11 权重匹配Weight 通过权重来匹配路由:
spring: cloud: gateway: routes: - id: weight_high uri: https://weighthigh.org predicates: - Weight=group1, 8 - id: weight_low uri: https://weightlow.org predicates: - Weight=group1, 2

3 功能强大的GatewayFilter Spring提供许多强大的GatewayFilter对请求进行处理。
3.1 添加请求头 给请求添加Header
spring: cloud: gateway: routes: - id: add_request_header_route uri: https://example.org predicates: - Path=/red/{segment} filters: - AddRequestHeader=X-Request-Red, Blue-{segment}

3.2 添加请求参数
spring: cloud: gateway: routes: - id: add_request_parameter_route uri: https://example.org predicates: - Host: {segment}.myhost.org filters: - AddRequestParameter=foo, bar-{segment}

3.3 添加返回Header
spring: cloud: gateway: routes: - id: add_response_header_route uri: https://example.org predicates: - Host: {segment}.myhost.org filters: - AddResponseHeader=foo, bar-{segment}

3.4 删除重复返回Header
spring: cloud: gateway: routes: - id: dedupe_response_header_route uri: https://example.org filters: - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

3.5 断路器Hystrix 简单配置:
spring: cloud: gateway: routes: - id: hystrix_route uri: https://example.org filters: - Hystrix=myCommandName

较复杂配置:
spring: cloud: gateway: routes: - id: hystrix_route uri: lb://backing-service:8088 predicates: - Path=/consumingserviceendpoint filters: - name: Hystrix args: name: fallbackcmd fallbackUri: forward:/incaseoffailureusethis - RewritePath=/consumingserviceendpoint, /backingserviceendpoint

3.6 断路器CircuitBreaker 简单配置:
spring: cloud: gateway: routes: - id: circuitbreaker_route uri: https://example.org filters: - CircuitBreaker=myCircuitBreaker

较复杂配置:
spring: cloud: gateway: routes: - id: circuitbreaker_route uri: lb://backing-service:8088 predicates: - Path=/consumingServiceEndpoint filters: - name: CircuitBreaker args: name: myCircuitBreaker fallbackUri: forward:/inCaseOfFailureUseThis - RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint

3. 7 请求头改名
spring: cloud: gateway: routes: - id: map_request_header_route uri: https://example.org filters: - MapRequestHeader=Blue, X-Request-Red

3.8 路径添加前缀 这个要注意和匹配路径区分,它是在匹配后再加个前缀:
spring: cloud: gateway: routes: - id: prefixpath_route uri: https://example.org filters: - PrefixPath=/mypath

请求/hello变成/mypath/hello
3.9 重定向
spring: cloud: gateway: routes: - id: prefixpath_route uri: https://example.org filters: - RedirectTo=302, https://acme.org

3.10 删除请求头
spring: cloud: gateway: routes: - id: removerequestheader_route uri: https://example.org filters: - RemoveRequestHeader=X-Request-Foo

3.11 删除返回头
spring: cloud: gateway: routes: - id: removeresponseheader_route uri: https://example.org filters: - RemoveResponseHeader=X-Response-Foo

3.12 删除请求参数
spring: cloud: gateway: routes: - id: removerequestparameter_route uri: https://example.org filters: - RemoveRequestParameter=red

3.13 重写路径
spring: cloud: gateway: routes: - id: rewritepath_route uri: https://example.org predicates: - Path=/red/** filters: - RewritePath=/red(?/?.*), $\{segment}

3.14 设置路径
spring: cloud: gateway: routes: - id: setpath_route uri: https://example.org predicates: - Path=/red/{segment} filters: - SetPath=/{segment}

3.15 设置请求头
spring: cloud: gateway: routes: - id: setrequestheader_route uri: https://example.org predicates: - Host: {segment}.myhost.org filters: - SetRequestHeader=foo, bar-{segment}

3.16 设置返回头
spring: cloud: gateway: routes: - id: setresponseheader_route uri: https://example.org predicates: - Host: {segment}.myhost.org filters: - SetResponseHeader=foo, bar-{segment}

3.17 设置返回状态码
spring: cloud: gateway: routes: - id: setstatusstring_route uri: https://example.org filters: - SetStatus=BAD_REQUEST - id: setstatusint_route uri: https://example.org filters: - SetStatus=401

3.18 去掉路径前缀
spring: cloud: gateway: routes: - id: nameRoot uri: https://nameservice predicates: - Path=/name/** filters: - StripPrefix=2

这配置请求/name/blue/red,实际就是请求nameservice/red,去掉两个前缀。
3.19 重试Retry GatewayFilter 想不到居然还有强大的重试功能:
spring: cloud: gateway: routes: - id: retry_test uri: http://localhost:8080/flakey predicates: - Host=*.retry.com filters: - name: Retry args: retries: 3 statuses: BAD_GATEWAY methods: GET,POST backoff: firstBackoff: 10ms maxBackoff: 50ms factor: 2 basedOnPreviousValue: false

3.20 请求大小限制
spring: cloud: gateway: routes: - id: request_size_route uri: http://localhost:8080/upload predicates: - Path=/upload filters: - name: RequestSize args: maxSize: 5000000

3.21 默认Filter 如果希望对所有路由都生效,可以添加默认Filter
spring: cloud: gateway: default-filters: - AddResponseHeader=X-Response-Default-Red, Default-Blue - PrefixPath=/httpbin

4 全局Global Filters 全局过滤器GlobalFilter接口和GatewayFilter的方法是一样的,但它是用于所有路由的。当请求过来时,整个Filter Chain是包含了所有的GlobalFilters和匹配上的GatewayFilters,执行顺序由getOrder()方法决定。
如下:
@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; } }

5 一切皆可自定义 Spring支持开发人员自定义PredicateGatewayFilterGlobalFilter
5.1 自定义Predicate
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory {public MyRoutePredicateFactory() { super(Config.class); }@Override public Predicate 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 } }

5.2 自定义GatewayFilter Pre的过滤器:
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory
{public PreGatewayFilterFactory() { super(Config.class); }@Override public GatewayFilter apply(Config config) { // grab configuration from Config object return (exchange, chain) -> { //If you want to build a "pre" filter you need to manipulate the //request before calling chain.filter ServerHttpRequest.Builder builder = exchange.getRequest().mutate(); //use builder to manipulate the request return chain.filter(exchange.mutate().request(builder.build()).build()); }; }public static class Config { //Put the configuration properties for your filter here } }

Post的过滤器:
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory {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 } }

5.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(); }

6 项目使用 添加依赖:
org.springframework.cloud spring-cloud-starter-gateway

配置Main启动应用:
package com.pkslow.cloud.gateway; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class GatewayService { public static void main(String[] args) { SpringApplication.run(GatewayService.class, args); } }

配置路由:
server: port: 8080 spring: cloud: gateway: routes: - id: pkslow uri: https://www.pkslow.com predicates: - Path=/pkslow/** filters: - RewritePath=/pkslow(?.*), /$\{segment}

启动后可正常访问了:
Spring Cloud Gateway简单入门,强大的微服务网关
文章图片

Spring Cloud Gateway简单入门,强大的微服务网关
文章图片

7 总结 Spring Cloud Gateway实在是非常强大,能满足微服务绝大多数应用场景了,还是很有必要了解一下的。
代码请查看:https://github.com/LarryDpk/p...
参考资料:官网
欢迎关注微信公众号<南瓜慢说>,将持续为你更新...
Spring Cloud Gateway简单入门,强大的微服务网关
文章图片

【Spring Cloud Gateway简单入门,强大的微服务网关】多读书,多分享;多写作,多整理。

    推荐阅读