1. SpringCloud 与 SpringBoot的版本映射关系
在已有的Spring Boot项目中增加Spring Cloud,首先要确定使用的Spring Cloud的版本,这取决于项目使用的Spring Boot的版本
SpringCloud 与 SpringBoot的版本映射关系
如果两者的版本不兼容,再会报: Spring Boot [2.x.x] is not compatible with this Spring Cloud release train
2. spring-cloud-gateway配置
Spring Cloud Gateway旨在提供一种简单而有效的方式来路由API服务,并为它们提供横切关注点,例如:安全性、监控/指标和弹性。
目前的版本信息:
2.1. 项目中如何包含spring-cloud-gateway
在项目中引入如下依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>3.0.8</version>
</dependency>
注意:
- 如果引入依赖,但不希望启用网关,请设置
spring.cloud.gateway.enabled=false
。 - Spring Cloud Gateway构建在
Spring Boot 2
、Spring WebFlux
、Project Reactor
之上,所以许多同步库(例如Spring Data
和Spring Security
)和模式可能不适用 - Spring Cloud Gateway需要
Spring Boot
和Spring Webflux
提供的Netty Runtime
。它不能在传统的Servlet
容器中工作,也不能作为WAR
构建。
2.2. 基本术语
Route 路由
: 网关的基本组成部分。它由一个ID、一个目标URI、一组谓词和一组过滤器定义。如果聚合谓词为真,则匹配路由。Predicate 谓词
: 一个Java 8函数谓词。输入类型为Spring Framework ServerWebExchange,在编程时可以匹配HTTP请求中的任何内容,例如 headers 或参数。Filter 过滤器:
使用特定工厂构造的GatewayFilter的实例,可以在发送下游请求之前或之后修改请求和响应。
2.3. 如何工作?
- 客户端向Spring Cloud Gateway发出请求。
- 如果
网关处理程序映射
确定请求与路由匹配,则将其发送到网关Web处理程序。 - 此处理程序通过特定于请求的过滤器链【filter chain】运行请求。
- 过滤器用虚线分隔的原因是过滤器可以在发送代理请求之前和之后运行逻辑。
- 执行所有“预”过滤器逻辑。然后发出代理请求。发出代理请求后,将运行“post”过滤器逻辑。
2.4. 如何配置?
- 路由谓词工厂 Route Predicate Factories 网关匹配路由作为
Spring WebFlux HandlerMapping
基础架构的一部分。Spring Cloud Gateway
包括许多内置的路由谓词工厂。所有这些谓词都匹配HTTP请求的不同属性。可以将多个路由谓词工厂与逻辑和语句组合在一起。 - Gateway 过滤器工厂 路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应。路由过滤器的作用域是特定的路由。Spring Cloud Gateway包括许多内置的GatewayFilter工厂。
路由谓词配置示例
即在spring boot的配置文件如application.yml中配置,配置示例如下:
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
- 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]
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
# The Weight Route Predicate Factory
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
路由过滤器配置示例
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
predicates:
- Path=/red/{segment}
filters:
- AddRequestHeader=X-Request-Red, Blue-{segment}
- id: add_request_parameter_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddRequestParameter=foo, bar-{segment}
- id: add_response_header_route
uri: https://example.org
predicates:
- Host: {segment}.myhost.org
filters:
- AddResponseHeader=foo, bar-{segment}
- id: prefixpath_route
uri: https://example.org
filters:
- PrefixPath=/mypath
- id: requestratelimiter_route
uri: https://example.org
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
- id: prefixpath_route
uri: https://example.org
filters:
- RedirectTo=302, https://acme.org
代码配置示例
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
//@formatter:off
RouteLocator routeLocator = builder.routes()
.route("path_route", r -> r.path("/get")
.uri("http://httpbin.org"))
.route("host_route", r -> r.host("*.myhost.org")
.uri("http://httpbin.org"))
.route("rewrite_route", r -> r.host("*.rewrite.org")
.filters(f -> f.rewritePath("/foo/(?<segment>.*)",
"/${segment}"))
.uri("http://httpbin.org"))
.route("circuitbreaker_route", r -> r.host("*.circuitbreaker.org")
.filters(f -> f.circuitBreaker(c -> c.setName("slowcmd")))
.uri("http://httpbin.org"))
.route("circuitbreaker_fallback_route", r -> r.host("*.circuitbreakerfallback.org")
.filters(f -> f.circuitBreaker(c -> c.setName("slowcmd").setFallbackUri("forward:/circuitbreakerfallback")))
.uri("http://httpbin.org"))
.route("limit_route", r -> r
.host("*.limited.org").and().path("/anything/**","/bnything/**")
.filters(f -> f.requestRateLimiter(c -> c.setRateLimiter(redisRateLimiter())))
.uri("http://httpbin.org"))
.route("websocket_route", r -> r.path("/echo")
.uri("ws://localhost:9000"))
.build();
return routeLocator;
}
3. Global Filter
GlobalFilter接口与GatewayFilter接口具有相同的签名。GlobalFilter是有条件地应用于所有路由的特殊过滤器。
当请求匹配路由时,过滤web处理程序将GlobalFilter的所有实例和GatewayFilter的所有路由特定实例添加到过滤器链中。这个组合过滤器链由org.springframework.core.Ordered接口排序,可以通过实现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;
}
}
4. 如何配置跨域CORS
spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "https://docs.spring.io"
allowedMethods:
- GET
5. http超时配置
- 全局配置
spring:
cloud:
gateway:
httpclient:
connect-timeout: 1000
response-timeout: 5s
- 特定路由配置
- id: per_route_timeouts
uri: https://example.org
predicates:
- name: Path
args:
pattern: /delay/{timeout}
metadata:
response-timeout: 200
connect-timeout: 200
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.CONNECT_TIMEOUT_ATTR;
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.RESPONSE_TIMEOUT_ATTR;
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeBuilder){
return routeBuilder.routes()
.route("test1", r -> {
return r.host("*.somehost.org").and().path("/somepath")
.filters(f -> f.addRequestHeader("header1", "header-value-1"))
.uri("http://someuri")
.metadata(RESPONSE_TIMEOUT_ATTR, 200)
.metadata(CONNECT_TIMEOUT_ATTR, 200);
})
.build();
}
6. Actuator API
开启配置:spring.cloud.gateway.actuator.verbose.enabled=true
下表总结了Spring Cloud Gateway执行器端点(注意每个端点都以/actuator/gateway
为基路径):
ID | HTTP Method | Description |
---|---|---|
globalfilters | GET | Displays the list of global filters applied to the routes. |
routefilters | GET | Displays the list of GatewayFilter factories applied to a particular route. |
refresh | POST | Clears the routes cache. |
routes | GET | Displays the list of routes defined in the gateway. |
routes/{id} | GET | Displays information about a particular route. |
routes/{id} | POST | Adds a new route to the gateway. |
routes/{id} | DELETE | Removes an existing route from the gateway. |
附录
spring-cloud-gateway 在使用时,还有很多其它需要关注的,详见官方使用文档spring-cloud-gateway reference