欢迎访问Spring Cloud中国社区

《重新定义Spring Cloud实战》由Spring Cloud中国社区倾力打造,基于Spring Cloud的Finchley.RELEASE版本,本书内容宽度足够广、深度足够深,而且立足于生产实践,直接从生产实践出发,包含大量生产实践的配置。欢迎加微信Software_King进群答疑,国内谁在使用Spring Cloud?欢迎登记

Spring Cloud Gateway揭秘之处理请求流程

xujin · 6年前 · 20308 ·

摘要:本篇文章主要从源码的角度揭秘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. @Override
  2. public Mono<Void> apply(HttpServerRequest request, HttpServerResponse response) {
  3. NettyDataBufferFactory bufferFactory = new NettyDataBufferFactory(response.alloc());
  4. ServerHttpRequest adaptedRequest;
  5. ServerHttpResponse adaptedResponse;
  6. try {
  7. adaptedRequest = new ReactorServerHttpRequest(request, bufferFactory);
  8. adaptedResponse = new ReactorServerHttpResponse(response, bufferFactory);
  9. }
  10. catch (URISyntaxException ex) {
  11. logger.error("Invalid URL " + ex.getMessage(), ex);
  12. response.status(HttpResponseStatus.BAD_REQUEST);
  13. return Mono.empty();
  14. }
  15. if (adaptedRequest.getMethod() == HttpMethod.HEAD) {
  16. adaptedResponse = new HttpHeadResponseDecorator(adaptedResponse);
  17. }
  18. return this.httpHandler.handle(adaptedRequest, adaptedResponse)
  19. .doOnError(ex -> logger.error("Handling completed with error", ex))
  20. .doOnSuccess(aVoid -> logger.debug("Handling completed with success"));
  21. }

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. @Override
  2. public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
  3. ServerWebExchange exchange = createExchange(request, response);
  4. return getDelegate().handle(exchange)
  5. .onErrorResume(ex -> handleFailure(request, response, ex))
  6. .then(Mono.defer(response::setComplete));
  7. }

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. @Override
  2. public Mono<Void> handle(ServerWebExchange exchange) {
  3. Route route = exchange.getRequiredAttribute(GATEWAY_ROUTE_ATTR);
  4. List<GatewayFilter> gatewayFilters = route.getFilters();
  5. List<GatewayFilter> combined = new ArrayList<>(this.globalFilters);
  6. combined.addAll(gatewayFilters);
  7. //TODO: needed or cached?
  8. AnnotationAwareOrderComparator.sort(combined);
  9. logger.debug("Sorted gatewayFilterFactories: "+ combined);
  10. return new DefaultGatewayFilterChain(combined).filter(exchange);
  11. }

2.4 执行Filter链

  1. private static class DefaultGatewayFilterChain implements GatewayFilterChain {
  2. private int index;
  3. private final List<GatewayFilter> filters;
  4. public DefaultGatewayFilterChain(List<GatewayFilter> filters) {
  5. this.filters = filters;
  6. }
  7. @Override
  8. public Mono<Void> filter(ServerWebExchange exchange) {
  9. if (this.index < filters.size()) {
  10. GatewayFilter filter = filters.get(this.index++);
  11. return filter.filter(exchange, this);
  12. }
  13. else {
  14. return Mono.empty(); // complete
  15. }
  16. }
  17. }

2.5 Gateway Filter委托为Gloable Filter执行

  1. private static class GatewayFilterAdapter implements GatewayFilter {
  2. private final GlobalFilter delegate;
  3. public GatewayFilterAdapter(GlobalFilter delegate) {
  4. this.delegate = delegate;
  5. }
  6. @Override
  7. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  8. return this.delegate.filter(exchange, chain);
  9. }
  10. @Override
  11. public String toString() {
  12. final StringBuilder sb = new StringBuilder("GatewayFilterAdapter{");
  13. sb.append("delegate=").append(delegate);
  14. sb.append('}');
  15. return sb.toString();
  16. }
  17. }

2.6 预告待续

在之后的文章中,将会揭秘Spring Cloud Gateway的架构设计,Filter链设计,以及启动装在流程等。