Soul网关源码阅读13-理解HTTP请求处理

Soul 是一个异步的,高性能的,跨语言的,响应式的API网关,主要基于Spring WebFlux 和 Netty 来实现。

来看下一些基础类的作用,对理解soul网关请求处理过程将有帮助。

  • org.springframework.http.server.reactive.HttpHandler
  • org.springframework.http.server.reactive.ReactorHttpHandlerAdapter
  • org.springframework.web.server.adapter.HttpWebHandlerAdapter
  • org.springframework.web.server.ServerWebExchange
  • org.springframework.web.server.WebHandler
  • org.dromara.soul.web.handler.SoulWebHandler

1、HttpHandler

org.springframework.http.server.reactive.HttpHandler
用来转化底层的 Http 请求响应语义,用来接收处理底层容器的 Http 请求

public interface HttpHandler {
   /**
    * Handle the given request and write to the response.
    * @param request current request
    * @param response current response
    * @return indicates completion of request handling
    */
   Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response);
}

2、WebHandler

org.springframework.web.server.WebHandler
可以对请求和响应做一些必要的处理,SoulWebHandler 实现了此接口,将ServerWebExchange进行链式处理。

public interface WebHandler {
   /**
    * Handle the web server exchange.
    * @param exchange the current server exchange
    * @return {@code Mono<Void>} to indicate when request handling is complete
    */
   Mono<Void> handle(ServerWebExchange exchange);
}

3、ServerWebExchange

org.springframework.web.server.ServerWebExchange
包装了请求和响应体

public interface ServerWebExchange {
	String LOG_ID_ATTRIBUTE = ServerWebExchange.class.getName() + ".LOG_ID";
	/**
	 * Return the current HTTP request.
	 */
	ServerHttpRequest getRequest();
	/**
	 * Return the current HTTP response.
	 */
	ServerHttpResponse getResponse();
	/**
	 * Return a mutable map of request attributes for the current exchange.
	 */
	Map<String, Object> getAttributes();
	......
}

4、ReactorHttpHandlerAdapter

org.springframework.http.server.reactive.ReactorHttpHandlerAdapter
转换 HttpHandler 请求,将 HttpServerRequest 封装成 ReactorServerHttpRequest,HttpServerResponse 封装成ReactorServerHttpResponse

@Override
public Mono<Void> apply(HttpServerRequest reactorRequest, HttpServerResponse reactorResponse) {
   NettyDataBufferFactory bufferFactory = new NettyDataBufferFactory(reactorResponse.alloc());
   try {
      ReactorServerHttpRequest request = new ReactorServerHttpRequest(reactorRequest, bufferFactory);
      ServerHttpResponse response = new ReactorServerHttpResponse(reactorResponse, bufferFactory);
      if (request.getMethod() == HttpMethod.HEAD) {
         response = new HttpHeadResponseDecorator(response);
      }
      return this.httpHandler.handle(request, response)
            .doOnError(ex -> logger.trace(request.getLogPrefix() + "Failed to complete: " + ex.getMessage()))
            .doOnSuccess(aVoid -> logger.trace(request.getLogPrefix() + "Handling completed"));
   }
   catch (URISyntaxException ex) {
      if (logger.isDebugEnabled()) {
         logger.debug("Failed to get request URI: " + ex.getMessage());
      }
      reactorResponse.status(HttpResponseStatus.BAD_REQUEST);
      return Mono.empty();
   }
}

5、HttpWebHandlerAdapter

org.springframework.web.server.adapter.HttpWebHandlerAdapter
将 request 和 response 封装到 ServerWebExchange

@Override
public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
   if (this.forwardedHeaderTransformer != null) {
      request = this.forwardedHeaderTransformer.apply(request);
   }
   ServerWebExchange exchange = createExchange(request, response);
   LogFormatUtils.traceDebug(logger, traceOn ->
         exchange.getLogPrefix() + formatRequest(exchange.getRequest()) +
               (traceOn ? ", headers=" + formatHeaders(exchange.getRequest().getHeaders()) : ""));
   return getDelegate().handle(exchange)
         .doOnSuccess(aVoid -> logResponse(exchange))
         .onErrorResume(ex -> handleUnresolvedError(exchange, ex))
         .then(Mono.defer(response::setComplete));
}

6、SoulWebHandler

org.dromara.soul.web.handler.SoulWebHandler
WebHandler的实现类,将ServerWebExchange在soul网关的插件链中进行传递。

/**
 * Handle the web server exchange.
 * @param exchange the current server exchange
 * @return {@code Mono<Void>} to indicate when request handling is complete
 */
@Override
public Mono<Void> handle(@NonNull final ServerWebExchange exchange) {
    MetricsTrackerFacade.getInstance().counterInc(MetricsLabelEnum.REQUEST_TOTAL.getName());
    Optional<HistogramMetricsTrackerDelegate> startTimer = MetricsTrackerFacade.getInstance().histogramStartTimer(MetricsLabelEnum.REQUEST_LATENCY.getName());
    return new DefaultSoulPluginChain(plugins).execute(exchange).subscribeOn(scheduler)
            .doOnSuccess(t -> startTimer.ifPresent(time -> MetricsTrackerFacade.getInstance().histogramObserveDuration(time)));
}

7、总结

1、ReactorHttpHandlerAdapter 转换 HttpHandler 请求,将 HttpServerRequest 封装成 ReactorServerHttpRequest,HttpServerResponse 封装成ReactorServerHttpResponse
2、HttpWebHandlerAdapter 处理封装Request 和 Response 为 ServerWebExchange
3、SoulWebHandler 接收ServerWebExchange,在soul 插件链中传递

参考:
Spring WebFlux 的设计及工作原理剖析
Spring Boot Reactor Netty配置 | Baeldung
背压(Back Pressure)与流量控制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值