版本:2.0.2.RELEASE
链接:http://spring.io/projects/spring-cloud-gateway#overview
本章主要目录如下:
Spring Cloud GatewayTLS/SSL是什么?
Spring Cloud Gateway因如何配置?
Spring Cloud Gateway跨域访问配置怎么玩?
Spring Cloud Gateway执行器API是什么?
Spring Cloud Gateway开发人员指南如何使用?
Spring Cloud Gateway应如何使用MVC或Webflux搭建?
本章主要内容如下:
1.Spring Cloud GatewayTLS/SSL是什么?
网关可以通过遵循通常的 Spring 服务器配置来监听 https 上的请求。例如:
application.yml
server:
ssl:
enabled: true
key-alias: scg
key-store-password: scg1234
key-store: classpath:scg-keystore.p12
key-store-type: PKCS12
网关路由可以路由到 http 和 https 后端。如果路由到 https 后端,则可以将网关配置为信任具有以下配置的所有下游证书:
application.yml
spring:
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true
使用不安全的信任管理器不适合生产。对于生产部署,可以使用以下配置配置一组可信任的已知证书:
application.yml
spring:
cloud:
gateway:
httpclient:
ssl:
trustedX509Certificates:
- cert1.pem
- cert2.pem
如果Spring Cloud Gateway未配置可信证书,则使用默认信任库(可以使用系统属性javax.net.ssl.trustStore覆盖)。
TLS握手
网关维护一个客户端池,用于路由到后端。通过https进行通信时,客户端会启动TLS握手。这次握手会有很多超时。可以配置这些超时(显示默认值):
application.yml
spring:
cloud:
gateway:
httpclient:
ssl:
handshake-timeout-millis:10000
close-notify-flush-timeout-millis:3000
close-notify-read-timeout-millis:0
2.Spring Cloud Gateway因如何配置?
Spring Cloud Gateway 的配置是由一系列的 RouteDefinitionLocator 类来管理的。
RouteDefinitionLocator.java。
public interface RouteDefinitionLocator {
Flux
}
默认情况下,PropertiesRouteDefinitionLocator 使用 Spring Boot 的@ConfigurationProperties 机制加载属性。
上面的配置示例都使用了一个使用位置参数而不是命名参数的快捷符号。以下两个例子是等效的:
application.yml
spring:
cloud:
gateway:
routes:
- id:setstatus_route
uri:http://example.org
filters:
- name:SetStatus
args:
status:401
- id:setstatusshortcut_route
uri:http://example.org
filters:
- SetStatus = 401
对于网关的一些用法,属性是足够的,但是一些生产用例将受益于从外部源(例如数据库)加载配置。未来的里程碑版本将RouteDefinitionLocator基于Spring Data Repositories实现,例如:Redis,MongoDB和Cassandra。
流式 Java 路由 API
为了允许在Java中进行简单配置,RouteLocatorBuilder bean中定义了一个流畅的API 。
GatewaySampleApplication.java.
// static imports from GatewayFilters and RoutePredicates
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) {
return builder.routes()
.route(r -> r.host("**.abc.org").and().path("/image/png")
.filters(f ->
f.addResponseHeader("X-TestHeader", "foobar"))
.uri("http://httpbin.org:80")
)
.route(r -> r.path("/image/webp")
.filters(f ->
f.addResponseHeader("X-AnotherHeader", "baz"))
.uri("http://httpbin.org:80")
)
.route(r -> r.order(-1)
.host("**.throttle.org").and().path("/get")
.filters(f -> f.filter(throttle.apply(1,
1,
10,
TimeUnit.SECONDS)))
.uri("http://httpbin.org:80")
)
.build();
}
这类风格也允许更多的自定义谓词断言。RouteDefinitionLocator bean 定义的谓词使用逻辑与组合。通过使用流式的 Java API,您可以在 Predicate 类上使用and(),or()和 negate()运算符。
DiscoveryClient 路由定义定位器
可以将网关配置为基于在 DiscoveryClient 兼容服务注册中心注册的服务来创建路由。要启用此功能,请设置 spring.cloud.gateway.discovery.locator.enabled = true 并确保
DiscoveryClient 实现类位于类路径上并已启用(例如 Netflix Eureka,Consul 或Zookeeper)。
3.Spring Cloud Gateway跨域访问配置怎么玩?
网关可以通过配置控制 CORS 行为。 “全局”CORS 配置是 Spring Framework CorsConfiguration的 URL 模式映射。
application.yml.
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "docs.spring.io"
allowedMethods:
- GET
在上面的示例中,对于所有 GET 请求的路径,将允许来自 docs.spring.io 的请求的 CORS请求。
4.Spring Cloud Gateway执行器API是什么?
TODO:编写/gateway 执行器端点文档
5.Spring Cloud Gateway开发人员指南如何使用?
TODO:编写自定义集成的概述
编写自定义路由谓词工厂
TODO:编写自定义路由谓词工厂文档
编写自定义网关过滤器工厂
要编写 GatewayFilter,您需要实现 GatewayFilterFactory。有一个名为AbstractGatewayFilterFactory 的抽象类,您可以扩展它。
PreGatewayFilterFactory.java.
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 change.filter
ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
//use builder to manipulate the request
return chain.filter(exchange.mutate().request(request).build());
};
}
public static class Config {
//Put the configuration properties for your filter here
}
}
PostGatewayFilterFactory.java.
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
}
}
编写自定义全局过滤器
TODO:编写自定义全局过滤器的文档
编写自定义路由定位器和写入器
TODO:编写自定义路由定位器和写入器的文档
6.Spring Cloud Gateway应如何使用MVC或Webflux搭建?
Spring Cloud Gateway提供了一个实用程序对象ProxyExchange,可以在常规Spring Web处理程序中将其用作方法参数。它通过反射HTTP谓词的方法支持基本的下游HTTP交换。使用MVC,它还支持通过该forward()方法转发到本地处理程序。要在类路径中使用ProxyExchange,只需包含正确的模块(spring-cloud-gateway-mvc或者spring-cloud-gateway-webflux)。
MVC 示例(代理一个到下游远程服务器的“/test”请求):
@RestController
@SpringBootApplication
public class GatewaySampleApplication {
@Value("${remote.home}")
private URI home;
@GetMapping("/test")
public ResponseEntity> proxy(ProxyExchange
return proxy.uri(home.toString() + "/image/png").get();
}
}
Webflux 也是如此:
@RestController
@SpringBootApplication
public class GatewaySampleApplication {
@Value("${remote.home}")
private URI home;
@GetMapping("/test")
public Mono
return proxy.uri(home.toString() + "/image/png").get();
}
}
ProxyExchange 上有一些便捷方法,使处理方法能够发现和增强传入请求的 URI 路径。例如,您可能希望提取路径的尾随元素以将其传递到下游:
@GetMapping("/proxy/path/**")
public ResponseEntity> proxyPath(ProxyExchange
String path = proxy.path("/proxy/path/");
return proxy.uri(home.toString() + "/foos/" + path).get();
}
Spring MVC 或 Webflux 的所有特性都可用于 Gateway 处理方法。例如,您可以注入请求头和查询参数,并且您可以使用映射注释中的声明来约束传入的请求。有关这些特性的更多详细信息,请参阅 Spring MVC 中的@RequestMapping 文档。
可以使用 ProxyExchange 上的 header()方法将头信息添加到下游响应中。
您还可以通过向 get()等方法添加映射器来操作响应头信息(以及响应中你喜欢的任何其他内容)。映射器是一个函数,它接收传入的 ResponseEntity 并将其转换为传出的ResponseEntity。
最高优先级的类支持处理让"sensitive"敏感头信息(默认情况下是"cookie"和"authorization")不往下游传递,并且对于"proxy"代理头信息处理为(x-forwarded-*)。
至此,2.0.2.RELEASE的Spring Cloud Gateway就介绍完毕。
接下来将会从demo中逐步解析,请你持续关注米兜Java,相关代码将会同步到gitee、github中。
本文对应公众号链接:https://mp.weixin.qq.com/s/7HlFm66kHrhMJRZ6vRTcWg
源码获取
1.gitee:https://gitee.com/StarskyBoy
2.github: https://github.com/StarskyBoy