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会更好。
它的工作原理如下图所示:
简单而言就是通过一连串的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实在是非常强大,能满足微服务绝大多数应用场景了,还是很有必要了解一下的。
如发现本站有涉嫌抄袭侵权/违法违规等内容,请联系我们举报!一经查实,本站将立刻删除。