Spring Cloud Gateway简单入门,强大的微服务网关
source link: https://www.pkslow.com/archives/spring-cloud-gateway-introduction
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
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: 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>/?.*), $\{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<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
@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 项目使用
添加依赖:
<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; @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>.*), /$\{segment}
启动后可正常访问了:
7 总结
Spring Cloud Gateway
实在是非常强大,能满足微服务绝大多数应用场景了,还是很有必要了解一下的。
代码请查看: https://github.com/LarryDpk/pkslow-samples
参考资料: 官网
欢迎关注微信公众号< 南瓜慢说 >,将持续为你更新...
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK