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)与流量控制