Soul 源码阅读(三)请求处理概览
简介
基于上篇:Soul 源码阅读(二)代码初步运行的配置,这次debug下请求处理的大致路径,验证网关模型的路径
详细流程记录
查看运行日志,寻找切入点
上篇中我们配置了 Divide 插件,让 http://localhost:9195 ,转发到了后台服务器 http://localhost:8082 上,首先不打断点运行,查看运行日志,找一个切入点:
o.d.soul.plugin.base.AbstractSoulPlugin : divide selector success match , selector name :neety8082
o.d.soul.plugin.base.AbstractSoulPlugin : divide selector success match , selector name :neety8082
o.d.s.plugin.httpclient.WebClientPlugin : The request urlPath is http://localhost:8082, retryTimes is 1
上面的日志中一个比较明显的 divide 相关的日志,是 AbstractSoulPlugin 打印出来的,win下双击shift,搜索 AbstractSoulPlugin 进入,发现是一个接口,IDEA左边向下的箭头查看它的实现,发现有一个熟系的 DividePlugin 实现类,点击进入,在一个明显的 doExecute 函数上打上断点,发起请求:http://localhost:9195
通过函数调用栈,发送调用的是 SoulWebHandler ,从下面的函数中可以大致看出这是一个循环遍历,遍历 plugins 进行操作
public Mono<Void> execute(final ServerWebExchange exchange) {
return Mono.defer(() -> {
if (this.index < plugins.size()) {
SoulPlugin plugin = plugins.get(this.index++);
Boolean skip = plugin.skip(exchange);
if (skip) {
return this.execute(exchange);
}
return plugin.execute(exchange, this);
}
return Mono.empty();
});
}
跟踪调用栈
再次往前看调用栈,发送 SoulWebHandler 调用了 SoulWebHandler 的 execute
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());
// new DefaultSoulPluginChain(plugins).execute(exchange) 明显的调用关系
return new DefaultSoulPluginChain(plugins).execute(exchange).subscribeOn(scheduler)
.doOnSuccess(t -> startTimer.ifPresent(time -> MetricsTrackerFacade.getInstance().histogramObserveDuration(time)));
}
再往前发现看不懂了,没用明显的函数传递关系,我们在上面的函数打上端口,重启程序,再次发送请求
断点进来后,查看调用栈,发送调用上面函数的是 DefaultWebFilterChain
public Mono<Void> filter(ServerWebExchange exchange) {
return Mono.defer(() -> {
// 当下面都为null的时候进行调用
return this.currentFilter != null && this.chain != null ? this.invokeFilter(this.currentFilter, this.chain, exchange) : this.handler.handle(exchange);
});
}
再往前查看,调用栈又看不懂了,再次在上面的函数打上断点,重启,发请求,下面就直接写类和相关函数,有特别的地方就叫点说明
来到 FilteringWebHandler
public Mono<Void> handle(ServerWebExchange exchange) {
return this.chain.filter(exchange);
}
继续来到 WebHandlerDecorator
public Mono<Void> handle(ServerWebExchange exchange) {
return this.delegate.handle(exchange);
}
来到 ExceptionHandlingWebHandler
public Mono<Void> handle(ServerWebExchange exchange) {
Mono completion;
try {
// 在这进行调用
completion = super.handle(exchange);
} catch (Throwable var5) {
completion = Mono.error(var5);
}
WebExceptionHandler handler;
for(Iterator var3 = this.exceptionHandlers.iterator(); var3.hasNext(); completion = completion.onErrorResume((ex) -> {
return handler.handle(exchange, ex);
})) {
handler = (WebExceptionHandler)var3.next();
}
return completion;
}
继续来到 HttpWebHandlerAdapter ,这个类有点关键,看到在前面一直传递的变量:exchange,exchange在这个类中生成,传递给后面的函数进行调用,而且是使用response和request生成的
public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
if (this.forwardedHeaderTransformer != null) {
request = this.forwardedHeaderTransformer.apply(request);
}
// 重点变量 exchange 的生成
ServerWebExchange exchange = this.createExchange(request, response);
LogFormatUtils.traceDebug(logger, (traceOn) -> {
return exchange

本文详细记录了Soul网关请求处理的流程,从HttpServerOperations的请求接收,经过过滤器、WebHandler、插件调用链,到DividePlugin的路由匹配,再到WebClientPlugin的后台请求及WebClientResponsePlugin的响应返回。通过对源码的逐步debug,揭示了Soul网关处理请求的关键步骤和核心组件。
最低0.47元/天 解锁文章
1767

被折叠的 条评论
为什么被折叠?



