spring cloud gateway启动An attempt was made to call a method that does not e(springcloud Gateway)

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:         predicates:        - After=2020-01-20T17:42:47.789-07:00[America/Denver]

2.2 时间匹配Before

表示在什么时间之前匹配路由:

spring:  cloud:    gateway:      routes:      - id: before_route        uri:         predicates:        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

2.3 时间段匹配Between

表示在什么时间段匹配路由:

spring:  cloud:    gateway:      routes:      - id: between_route        uri:         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:         predicates:        - Cookie=chocolate, ch.p

2.5 请求头匹配Header

表示通过判断Http请求的Header来匹配路由:

spring:  cloud:    gateway:      routes:      - id: header_route        uri:         predicates:        - Header=X-Request-Id, d+

2.6 主机名匹配Host

通过判断Hostname来匹配路由:

spring:  cloud:    gateway:      routes:      - id: host_route        uri:         predicates:        - Host=**.somehost.org,**.anotherhost.org

2.7 请求方法匹配Method

表示通过判断请求方法来匹配路由:

spring:  cloud:    gateway:      routes:      - id: method_route        uri:         predicates:        - Method=GET,POST

2.8 请求路径匹配Path

表示通过判断请求路径来匹配路由,很常用:

spring:  cloud:    gateway:      routes:      - id: path_route        uri:         predicates:        - Path=/red/{segment},/blue/{segment}

2.9 请求参数匹配Query

表示通过判断请求参数来匹配路由:

spring:  cloud:    gateway:      routes:      - id: query_route        uri:         predicates:        - Query=red, gree.

2.10 IP地址匹配RemoteAddr

表示通过判断IP地址来匹配路由:

spring:  cloud:    gateway:      routes:      - id: remoteaddr_route        uri:         predicates:        - RemoteAddr=192.168.1.1/24

2.11 权重匹配Weight

通过权重来匹配路由:

spring:  cloud:    gateway:      routes:      - id: weight_high        uri:         predicates:        - Weight=group1, 8      - id: weight_low        uri:         predicates:        - Weight=group1, 2

3 功能强大的GatewayFilter

Spring提供许多强大的GatewayFilter对请求进行处理。

3.1 添加请求头

给请求添加Header:

spring:  cloud:    gateway:      routes:      - id: add_request_header_route        uri:         predicates:        - Path=/red/{segment}        filters:        - AddRequestHeader=X-Request-Red, Blue-{segment}

3.2 添加请求参数

spring:  cloud:    gateway:      routes:      - id: add_request_parameter_route        uri:         predicates:        - Host: {segment}.myhost.org        filters:        - AddRequestParameter=foo, bar-{segment}

3.3 添加返回Header

spring:  cloud:    gateway:      routes:      - id: add_response_header_route        uri:         predicates:        - Host: {segment}.myhost.org        filters:        - AddResponseHeader=foo, bar-{segment}

3.4 删除重复返回Header

spring:  cloud:    gateway:      routes:      - id: dedupe_response_header_route        uri:         filters:        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

3.5 断路器Hystrix

简单配置:

spring:  cloud:    gateway:      routes:      - id: hystrix_route        uri:         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:         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:         filters:        - MapRequestHeader=Blue, X-Request-Red

3.8 路径添加前缀

这个要注意和匹配路径区分,它是在匹配后再加个前缀:

spring:  cloud:    gateway:      routes:      - id: prefixpath_route        uri:         filters:        - PrefixPath=/mypath

请求/hello变成/mypath/hello。

3.9 重定向

spring:  cloud:    gateway:      routes:      - id: prefixpath_route        uri:         filters:        - RedirectTo=302, 

3.10 删除请求头

spring:  cloud:    gateway:      routes:      - id: removerequestheader_route        uri:         filters:        - RemoveRequestHeader=X-Request-Foo

3.11 删除返回头

spring:  cloud:    gateway:      routes:      - id: removeresponseheader_route        uri:         filters:        - RemoveResponseHeader=X-Response-Foo

3.12 删除请求参数

spring:  cloud:    gateway:      routes:      - id: removerequestparameter_route        uri:         filters:        - RemoveRequestParameter=red

3.13 重写路径

spring:  cloud:    gateway:      routes:      - id: rewritepath_route        uri:         predicates:        - Path=/red/**        filters:        - RewritePath=/red(?<segment>/?.*), ${segment}

3.14 设置路径

spring:  cloud:    gateway:      routes:      - id: setpath_route        uri:         predicates:        - Path=/red/{segment}        filters:        - SetPath=/{segment}

3.15 设置请求头

spring:  cloud:    gateway:      routes:      - id: setrequestheader_route        uri:         predicates:        - Host: {segment}.myhost.org        filters:        - SetRequestHeader=foo, bar-{segment}

3.16 设置返回头

spring:  cloud:    gateway:      routes:      - id: setresponseheader_route        uri:         predicates:        - Host: {segment}.myhost.org        filters:        - SetResponseHeader=foo, bar-{segment}

3.17 设置返回状态码

spring:  cloud:    gateway:      routes:      - id: setstatusstring_route        uri:         filters:        - SetStatus=BAD_REQUEST      - id: setstatusint_route        uri:         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()方法决定。

如下:

@Beanpublic GlobalFilter customFilter() {    return new CustomGlobalFilter();}public class CustomGlobalFilter implements GlobalFilter, Ordered {    @Override    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {        log.info("custom global filter");        return chain.filter(exchange);    }    @Override    public int getOrder() {        return -1;    }}

5 一切皆可自定义

Spring支持开发人员自定义Predicate、GatewayFilter和GlobalFilter。

5.1 自定义Predicate

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    }}

5.2 自定义GatewayFilter

Pre的过滤器:

public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {    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<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    }}

5.3 自定义GlobalFilter

@Beanpublic 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);}@Beanpublic 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 项目使用

添加依赖:

<dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-gateway</artifactId></dependency>

配置Main启动应用:

package com.pkslow.cloud.gateway;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class GatewayService {    public static void main(String[] args) {        SpringApplication.run(GatewayService.class, args);    }}

配置路由:

server:  port: 8080spring:  cloud:    gateway:      routes:      - id: pkslow        uri:         predicates:        - Path=/pkslow/**        filters:        - RewritePath=/pkslow(?<segment>.*), /${segment}

启动后可正常访问了:

7 总结

Spring Cloud Gateway实在是非常强大,能满足微服务绝大多数应用场景了,还是很有必要了解一下的。

本站部分内容由互联网用户自发贡献,该文观点仅代表作者本人,本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如发现本站有涉嫌抄袭侵权/违法违规等内容,请联系我们举报!一经查实,本站将立刻删除。