dubbo filter加载类
最近应用项目接入sentinel,但公司内部进行封装的sentinel filter好像一直加载不到,因此就从filter加载过程进行debug。
记录一下dubbo加载SPI的时候的方式。
源码中,spring启动时doCreateBean方法里,dubbo启动读取服务配置时,初始化ServiceConfig、ReferenceConfig(服务provider注册、服务consumer subscribe)时调用org.apache.dubbo.common.extension.ExtensionLoader进行加载SPI扩展。
调用链路为
ReferenceConfig.init ->
ReferenceConfig.createProxy ->
ProtocolFilterWrapper.refer ->
ProtocolListenerWrapper.refer ->
RegistryProtocol.refer(实际实现的是Protocol.refer) ->
省略一堆订阅消费服务的过程(不同注册中心调用的类不同,公司中用的是nacos,NacosRegistry.java中notify发现消费的服务)...
-> 订阅后就回到了ProtocolFilterWrapper.buildInvokerChain(就是这个地方,对所有org.apache.dubbo.rpc.Filter的资源扫描,ExtensionLoader进行加载Filter具体类,然后给consumer进行代理)
在buildInvokerChain中比较重要的就是这行
List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);
ExtensionLoader.getExtensionLoader(Filter.class)初始化ExtensionLoader并加载有关dubbo filter的类,链路为ExtensionLoader.getExtensionLoader() -> ExtensionLoader.getAdaptiveExtension() -> ExtensionLoader.createAdaptiveExtension() -> ExtensionLoader.getAdaptiveExtensionClass() -> ExtensionLoader.getExtensionClasses() -> ExtensionLoader.loadExtensionClasses() -> ExtensionLoader.loadDirectory() -> ExtensionLoader.loadResource()。
debug链路这里一直是没有问题的,sentinel的filter也一直有加载,问题就出在getActivateExtension(invoker.getUrl(), key, group);里。
ExtensionLoader里面
public List<T> getActivateExtension(URL url, String[] values, String group)
List<String> names = values == null ? new ArrayList<>(0) : asList(values);
发现url:dubbo://10.218.15.208:20880/com.xx.xx.user.api.TokenApi?application=sl-saas-member&application.version=1.0.0&category=providers&check=false&cluster=failfast&deprecated=false&dubbo=2.0.2&init=false&interface=com.xx.xx.user.api.TokenApi&logger=slf4j&path=com.xx.xx.user.api.TokenApi&pid=24428&protocol=dubbo&qos.enable=false&reference.filter=-validation,-sentinel.dubbo.consumer.filter®ister.ip=172.26.85.15&release=2.7.8&remote.application=sl-saas-user&revision=1.0.0-20220223.020357-47&side=consumer&sticky=false&timeout=3000×tamp=1646037857016&validation=false&version=1.0.0
然后在获取values的时候存在-validation,-sentinel.dubbo.consumer.filter
-sentinel.dubbo.consumer.filter就表示不加上这个filter。
因为这个在ExtensionLoader.getActivateExtension(URL url, String[] values, String group)里有这个代码
if (isMatchGroup(group, activateGroup)
&& !names.contains(name)
&& !names.contains(REMOVE_VALUE_PREFIX + name)//不是应该去除的配置名
&& isActive(activateValue, url)) {
activateExtensions.add(getExtension(name));
}
那么为什么要在reference上加上这个配置,大概是因为这边使用的sentinel版本比较老旧,不太适用,所以去掉。
配置是什么时候加上的呢?
有两种方式
1.在properties文件或者apollo的配置上加上dubbo.consumer.filter=xxx或者dubbo.provider.filter=xxxx
2.公司目前是在DubboConfigBeanPostProcessor implements BeanPostProcessor里写死了config.setFilter把不需要用的filter写入。
在自己封装的sentinel框架中,也重新实现了SentinelDubboConfigBeanPostProcessor implements BeanPostProcessor, EnvironmentAware,
里面会有对两配置是否启用dubbo provider、consumer的filter进行判断,如果为false,就自动加入-filterName,来移除filter。
新更新:如果有重复的filter key名字配置,但value是不同的类,那么会随机加载一个,另外一个就不生效了,具体加载哪个,是根据包扫描的顺序决定的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下