Soul 网关源码学习(13) - Soul 网关插件处理的详细流程

soul 网关中插件的定义

插件是 soul 网关的核心概念, soul 的特性都是基于插件实现的, soul 中插件的接口定义在模块 soul-plugin-api 中, 其主要的方法如下:

public interface SoulPlugin {

Mono<Void> execute(ServerWebExchange exchange, SoulPluginChain chain);

int getOrder();

default String named() {
return "";
}

default Boolean skip(ServerWebExchange exchange) {
return false;
}
}
  • execute 方法定义了 soul 插件逻辑的执行入口
  • getOrder 约束接口要求了所有的实现类需要在这个接口的实现里面返回 int 类型的插件顺序, 这个顺序在组织网关的插件链的时候会决定网关请求上下文在插件处理链上的处理的顺序

组织插件链的时候会根据 order 排序, 详细的处理在 org.dromara.soul.web.configuration.SoulConfiguration#soulWebHandler 中的 final List<SoulPlugin> soulPlugins = pluginList.stream().sorted(Comparator.comparingInt(SoulPlugin::getOrder)).collect(Collectors.toList());
排好序之后的插件列表会作为 SoulWebHandler 的构造函数影响 SoulWebHandler 中处理网关请求过程中插件链中插件链的处理顺序。

  • named 约束接口要求了所有的实现类需要在这个接口的实现里面返回插件的名称
  • skip 接口根据传入的 ServerWebExchange 中的网关请求上下文信息判断是否跳过一个插件的处理

soul 网关插件链处理

插件链的处理流程可以用下图描述

plugin_chain_schedule.png

soul-web 模块中的 SoulWebHandler 是处理 soul 网关请求的关键类, 在它的 execute 方法中, 可以看到它会实例化 DefaultSoulPluginChain 对象后然后调用它的 execute 方法, DefaultSoulPluginChain 对象的 execute 方法如下:

@Override
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();
});
}

execute 方法中使用了 Mono 对象的静态方法 defer, 注释中对 defer 方法的描述是: “Create a Mono provider that will supply a target Mono to subscribe to for each Subscriber downstream”, 也就是说当返回的
Mono 对象被 subscribe 的时候才会调用 defer 方法的入参, 它的入参对象是个 Supplier。这个 Supplier 方法体的内部执行的就是插件链中插件链条的处理逻辑:

  • 每次请求都会实例化一个新的 DefaultSoulPluginChain 对象,多个请求的插件链互不干扰
  • 一个请求执行到插件链的进度由 DefaultSoulPluginChain 对象实例中的 index 标识
  • 通过 SoulPluginskip 方法判断是否跳过当前插件的处理
    • 跳过处理的方法是调用当前实例的 execute 方法,因为 index 变量已经自增, 所以跳过处理调用当前实例的 execute 方法之后会处理插件链条中当前插件节点的下一个插件节点
    • 如果不跳过处理, 执行插件的 execute 方法, ServerWebExchange 信息和当前的插件链信息传入让插件链往下执行
文章作者: David Liu
文章链接: https://davidliu.now.sh/2021/01/28/soul_plugin_chain_execute/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 David Liu's Blog