基本概念
Route
路由器=ID+URI+Predicates+Filters
路由器决定如何处理请求, 当一个请求到来的时候, 跟据匹配条件找到路由器, 再由路由器的过滤器来处理请求.
Predicate
匹配器, 是一个java8的函数,输入是ServerWebChange, 里面包含了ServerHttpRequest, 开发者跟据输入决定是否匹配路由.
Filter
过滤器, 处理请求, 可以修改请求前的数据和返回后的数据, 类似于spring webmvc的web过滤器.
How it works
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都不能多次读, 需要自定义装饰器封装实现多次读的功能.
失败重试
这个没有全局过滤器, 需要自己实现.