文章导航
摘要:本篇文章主要从源码的角度揭秘Spring Cloud Gateway的怎么处理请求流程。
1.Spring Gateway概述
Spring Cloud Gateway
是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代Netflix ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。
2. Spring Cloud gateway请求入口分析
不管是Zuul,还是Spring Cloud Gateway还是基于Netty的自研网关,都会把请求进来的Request,或者返回的Response进行包装,转换提取为网关运行的上下文信息,而在Spring Cloud gateway中网关的上下文为ServerWebExchange。
2.1 入口HttpServerRequest和HttpServerResponse转换
Spring Cloud Gateway的请求入口,org.springframework.http.server.reactive.ReactorHttpHandlerAdapter#apply方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @Override public Mono<Void> apply(HttpServerRequest request, HttpServerResponse response) { NettyDataBufferFactory bufferFactory = new NettyDataBufferFactory(response.alloc()); ServerHttpRequest adaptedRequest; ServerHttpResponse adaptedResponse; try { adaptedRequest = new ReactorServerHttpRequest(request, bufferFactory); adaptedResponse = new ReactorServerHttpResponse(response, bufferFactory); } catch (URISyntaxException ex) { logger.error("Invalid URL " + ex.getMessage(), ex); response.status(HttpResponseStatus.BAD_REQUEST); return Mono.empty(); } if (adaptedRequest.getMethod() == HttpMethod.HEAD) { adaptedResponse = new HttpHeadResponseDecorator(adaptedResponse); } return this.httpHandler.handle(adaptedRequest, adaptedResponse) .doOnError(ex -> logger.error("Handling completed with error", ex)) .doOnSuccess(aVoid -> logger.debug("Handling completed with success")); }
|
PS,代码来源于spring-web-5.0.4.RELEASE.jar
此方法为Spring Cloud Gateway的请求入口方法,该方法的作用就是把接收到的HttpServerRequest或者最终需要返回的HttpServerResponse,包装转换为ReactorServerHttpRequest和ReactorServerHttpResponse。
2.2 构造Spring Cloud gateway的上下文ServerWebExchange
在org.springframework.web.server.adapter.HttpWebHandlerAdapter的182行,代码如下所示:
1 2 3 4 5 6 7
| @Override public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) { ServerWebExchange exchange = createExchange(request, response); return getDelegate().handle(exchange) .onErrorResume(ex -> handleFailure(request, response, ex)) .then(Mono.defer(response::setComplete)); }
|
createExchange()将ServerHttpRequest ServerHttpResponse构建网关上下文ServerWebExchange。
PS:其中org.springframework.web.server.handler.WebHandlerDecorator.getDelegate()通过委托的方式获取一系列需要处理的WebHandler.
2.3 进入Filter链
org.springframework.cloud.gateway.handler.FilteringWebHandler#handle方法,即77行,代码如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Override public Mono<Void> handle(ServerWebExchange exchange) { Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR); List<GatewayFilter> gatewayFilters = route.getFilters(); List<GatewayFilter> combined = new ArrayList<>(this.globalFilters); combined.addAll(gatewayFilters); AnnotationAwareOrderComparator.sort(combined); logger.debug("Sorted gatewayFilterFactories: "+ combined); return new DefaultGatewayFilterChain(combined).filter(exchange); }
|
2.4 执行Filter链
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| private static class DefaultGatewayFilterChain implements GatewayFilterChain { private int index; private final List<GatewayFilter> filters; public DefaultGatewayFilterChain(List<GatewayFilter> filters) { this.filters = filters; } @Override public Mono<Void> filter(ServerWebExchange exchange) { if (this.index < filters.size()) { GatewayFilter filter = filters.get(this.index++); return filter.filter(exchange, this); } else { return Mono.empty(); } } }
|
2.5 Gateway Filter委托为Gloable Filter执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| private static class GatewayFilterAdapter implements GatewayFilter { private final GlobalFilter delegate; public GatewayFilterAdapter(GlobalFilter delegate) { this.delegate = delegate; } @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { return this.delegate.filter(exchange, chain); } @Override public String toString() { final StringBuilder sb = new StringBuilder("GatewayFilterAdapter{"); sb.append("delegate=").append(delegate); sb.append('}'); return sb.toString(); } }
|
2.6 预告待续
在之后的文章中,将会揭秘Spring Cloud Gateway的架构设计,Filter链设计,以及启动装在流程等。
如果您觉得文章不错,可以打赏我喝一杯咖啡!
微信打赏
支付宝打赏