Soul网关源码分析-7期(番外)
程序员文章站
2022-06-03 20:24:13
...
开个小差, 追下网关的接收请求并转发中, soul借助 spring-web 的实现.
追下网关监听请求的开启, 找到配置类 SoulConfiguration
:
@Configuration
public class SoulNettyWebServerFactory {
private static final int DEFAULT_IO_WORKER_COUNT = Integer.parseInt(System.getProperty(
ReactorNetty.IO_WORKER_COUNT,
"" + Math.max(Runtime.getRuntime()
.availableProcessors() << 1, 16)));
@Bean
public NettyReactiveWebServerFactory nettyReactiveWebServerFactory() {
NettyReactiveWebServerFactory webServerFactory = new NettyReactiveWebServerFactory();
webServerFactory.addServerCustomizers(new EventLoopNettyCustomizer());
return webServerFactory;
}
}
这里应该是借助 Spring-web 框架 启动 Netty 的开始了.
再关注下另一个配置类 SoulConfiguration
:
@Configuration
public class SoulConfiguration {
@Bean("webHandler")
public SoulWebHandler soulWebHandler(final ObjectProvider<List<SoulPlugin>> plugins) {
List<SoulPlugin> pluginList = plugins.getIfAvailable(Collections::emptyList);
final List<SoulPlugin> soulPlugins = pluginList.stream()
.sorted(Comparator.comparingInt(SoulPlugin::getOrder)).collect(Collectors.toList());
soulPlugins.forEach(soulPlugin -> log.info("loader plugin:[{}] [{}]", soulPlugin.named(), soulPlugin.getClass().getName()));
// 这里初始化 SoulWebHandler
return new SoulWebHandler(soulPlugins);
}
}
这里初始化了 SoulWebHandler
类, 这个类是插件链的关键, 分析下他到底为啥在请求中会被调用:
public final class SoulWebHandler implements WebHandler {
@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))
);
}
}
SoulWebHandler
实现 spring-web 框架的WebHandler
并实现 handle()
, 这是框架链上一环, 请求时肯定也会被调用.
我们知道这个 SoulWebHandler
的插件链, 最最主要的功能就是请求转发并接受响应, 这里借助 spring-web 框架的 exchange
上下文, 在运行过程中将响应信息注入其中, 即可完成使命.
而后续我猜测 spring-web 框架也会订阅这整个Web链的Mono, 就能阻塞住请求线程, 即可在得到响应信息后返回.