文档:
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.0.2.RELEASE/single/spring-cloud-gateway.html
路由器=ID+URI+Predicates+Filters
路由器决定如何处理请求, 当一个请求到来的时候, 跟据匹配条件找到路由器, 再由路由器的过滤器来处理请求.
匹配器, 是一个java8的函数,输入是ServerWebChange, 里面包含了ServerHttpRequest, 开发者跟据输入决定是否匹配路由.
过滤器, 处理请求, 可以修改请求前的数据和返回后的数据, 类似于spring webmvc的web过滤器.
spring cloud gateway默认有很多全局过滤器和普通过滤器, 可以通过配置文件配置发挥强大功效.
spring cloud gateway 基于spring webflux, 而不是spring webmvc, 这一点要非常注意,如果classpath包含了spring webmvc那么启动后,网关路由不会生效.
dependencies {
compile('org.springframework.cloud:spring-cloud-starter')
compile('org.springframework.cloud:spring-cloud-starter-gateway')
compile('org.springframework.boot:spring-boot-starter-webflux')
}
configurations {
all*.exclude group: 'org.springframework','spring-webmvc'
}
启动成功后,应该输出:
INFO org.springframework.boot.web.embedded.netty.NettyWebServer - Netty started on port(s): …
微服务网关最重要的几个功能分别是路由, 负载均衡,认证授权, 跨域配置, 日志, 失败重试, 下来一一来配置.
通常微服务都是注册中心, 服务都是自动发现的,spring cloud gateway可以基于注册小心动态配置路由, 转发的规则是:
/service_id/path->转发到service_id对应的服务
只需要添加配置:
spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.gateway.discovery.locator.lowerCaseServiceId=true
就能动态路由.
以lb://开头的请求, 会被全局过滤器RetryLoadBalancerClientFilter拦截并进行负载均衡处理, 所有的动态路由都会自动负载均衡.
有一个专门用来做认证授权的服务, 网关需要做的就是自定义一个全局过滤器, 将每一个请求发到授权服务进行认证授权.
@Component
public class AuthFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
return Constants.PRE_FILTER_ORDER_AUTH;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
try {
//TODO 调用授权服务进行认证和授权
return chain.filter(exchange.mutate().request(request).build());
} catch (Exception e) {
log.error("auth failed: " + e.getMessage());
return exchange.getResponse()
.writeWith(Flux.just(exchange.getResponse().bufferFactory().wrap("授权失败".getBytes())));
}
}
有时候前端需要支持跨域访问, 这里简单配置允许所有域名访问.
spring.cloud.gateway.globalcors.cors-configurations.[/**].allowed-origins=* spring.cloud.gateway.globalcors.cors-configurations.[/**].allowed-methods=* spring.cloud.gateway.globalcors.cors-configurations.[/**].allowed-headers=* spring.cloud.gateway.globalcors.cors-configurations.[/**].allow-credentials=true
日志功能同样是自定义全局过滤器实现, 在请求进入时打印输入日志,返回时打印输出日志, 唯一的问题是在打印请求或返回的body时要处理下,一般情况下请求和响应的body都不能多次读, 需要自定义装饰器封装实现多次读的功能.
#失败重试
这个没有全局过滤器, 需要自己实现.