dubbo 3.2.0 的filterChain 简要分析

news2024/9/27 15:26:49

dubbo 3.2.0 的filterChain 的核心类是DefaultFilterChainBuilder 。

Builder

public class DefaultFilterChainBuilder implements FilterChainBuilder {

的buildInvokerChain函数
在这里插入图片描述
对于consumer refer

 @Override
    public <T> Invoker<T> buildInvokerChain(final Invoker<T> originalInvoker, String key, String group) 

的参数如上图,如果是provider,group值不同。

dubbo 通group识别出带有@Activate annotation的filter,并按照order进行排序。

/**
 * TraceFilter
 */
@Activate(group = CommonConstants.PROVIDER)
public class TraceFilter implements Filter {
   
@Activate(group = CONSUMER, order = Integer.MIN_VALUE)
public class ConsumerContextFilter implements ClusterFilter, ClusterFilter.Listener {
  
  @Activate(group = CONSUMER,onClass = "org.apache.dubbo.metrics.collector.DefaultMetricsCollector")
public class MetricsClusterFilter implements ClusterFilter, BaseFilter.Listener, ScopeModelAware {
  @Activate(group = CONSUMER, order = -1, onClass = "io.micrometer.observation.NoopObservationRegistry")
public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listener, ScopeModelAware {

consumer 默认的filter如下
在这里插入图片描述
FutureFilter是异步future调用的处理

@Override
public void onResponse(Result result, Invoker<?> invoker, Invocation invocation) {
if (result.hasException()) {
fireThrowCallback(invoker, invocation, result.getException());
} else {
fireReturnCallback(invoker, invocation, result.getValue());
}
}

@Override
public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {
    fireThrowCallback(invoker, invocation, t);
}

后面3个都是可观察性相关。

调用过程

stack信息

buildClusterInvokerChain:86, DefaultFilterChainBuilder (org.apache.dubbo.rpc.cluster.filter)
<init>:87, AbstractCluster$ClusterFilterInvoker (org.apache.dubbo.rpc.cluster.support.wrapper)
buildClusterInterceptors:47, AbstractCluster (org.apache.dubbo.rpc.cluster.support.wrapper)
join:61, AbstractCluster (org.apache.dubbo.rpc.cluster.support.wrapper)
join:39, MockClusterWrapper (org.apache.dubbo.rpc.cluster.support.wrapper)
join:40, ScopeClusterWrapper (org.apache.dubbo.rpc.cluster.support.wrapper)
doCreateInvoker:583, RegistryProtocol  

类MockClusterWrapper的

@Override
public <T> Invoker<T> join(Directory<T> directory, boolean buildFilterChain) throws RpcException {
    return new MockClusterInvoker<T>(directory,
            this.cluster.join(directory, buildFilterChain));
}

调用public abstract class AbstractCluster 的

  @Override
    public <T> Invoker<T> join(Directory<T> directory, boolean buildFilterChain) throws RpcException {
        if (buildFilterChain) {
 
            return buildClusterInterceptors(doJoin(directory));
        } else {
            return doJoin(directory);
        }
    }

然后调用到

public ClusterFilterInvoker(AbstractClusterInvoker<T> invoker) {
    List<FilterChainBuilder> builders = ScopeModelUtil.getApplicationModel(invoker.getUrl().getScopeModel()).getExtensionLoader(FilterChainBuilder.class).getActivateExtensions();
    if (CollectionUtils.isEmpty(builders)) {
        filterInvoker = invoker;
    } else {
        ClusterInvoker<T> tmpInvoker = invoker;
        for (FilterChainBuilder builder : builders) {
            tmpInvoker = builder.buildClusterInvokerChain(tmpInvoker, REFERENCE_FILTER_KEY, CommonConstants.CONSUMER);
        }
        filterInvoker = tmpInvoker;
    }
}

可以看到,可以扩展builder 进行filter组装,在循环过程中调用到DefaultFilterChainBuilder的buildClusterInvokerChain。

@Override
    public <T> ClusterInvoker<T> buildClusterInvokerChain(final ClusterInvoker<T> originalInvoker, String key, String group) {
        ClusterInvoker<T> last = originalInvoker;
        URL url = originalInvoker.getUrl();
        List<ModuleModel> moduleModels = getModuleModelsFromUrl(url);
        List<ClusterFilter> filters;
        if (moduleModels != null && moduleModels.size() == 1) {
            filters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, moduleModels.get(0)).getActivateExtension(url, key, group);
        } else if (moduleModels != null && moduleModels.size() > 1) {
            filters = new ArrayList<>();
            List<ExtensionDirector> directors = new ArrayList<>();
            for (ModuleModel moduleModel : moduleModels) {
                List<ClusterFilter> tempFilters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, moduleModel).getActivateExtension(url, key, group);
                filters.addAll(tempFilters);
                directors.add(moduleModel.getExtensionDirector());
            }
            filters = sortingAndDeduplication(filters, directors);

        } else {
            filters = ScopeModelUtil.getExtensionLoader(ClusterFilter.class, null).getActivateExtension(url, key, group);
        }

        if (!CollectionUtils.isEmpty(filters)) {
            for (int i = filters.size() - 1; i >= 0; i--) {
                final ClusterFilter filter = filters.get(i);
                final Invoker<T> next = last;
                last = new CopyOfClusterFilterChainNode<>(originalInvoker, next, filter);
            }
            return new ClusterCallbackRegistrationInvoker<>(originalInvoker, last, filters);
        }

        return last;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/657063.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java自动化测试(web自动化测试框架 )

测试数据 测试地址 http://120.78.128.25:8765/ 投资人 13323234545 lemon123456 借款人 13323234444 lemonbest 后台地址 http://120.78.128.25:8765/Admin/Index/login.html lemon7 lemonbest Page Object PO简介 https://www.selenium.dev/documentation/en/g…

如何把在线K歌“玩起来”——专访撕歌音视频架构师程乐

编者按&#xff1a;在线K歌的业务已经发展了十年&#xff0c;程乐在音视频领域也闯荡了十年&#xff0c;甚至更久。为什么选择在线K歌领域&#xff1f;如何走过“漫长的季节”&#xff0c;迎来新的风景&#xff1f;如何在“在线K歌”这块难啃的骨头里分点肉&#xff1f;在这一连…

【存储】cache memory、primary memory and secondary memory

一、提要二、计算机的存储结构三、高速缓存&#xff1a;cache memory四、主存&#xff1a;Primary memory4.1 RAM4.11 SRAM 和 DRAM的概念4.12 SRAM 和 DRAM的应用场景 4.2 ROM4.21 PROM4.22 EPROM▶ EEPROM▶ UVEPROM 五、辅助存储器&#xff1a;secondary memory六、单片机的…

redis的4种模式,单机,哨兵、主从复制、集群

为了redis叫做redis服务器&#xff1f; 因为在运行时&#xff0c;在进行工作时是一个被注册一个进程(服务)&#xff0c;我们把他叫做一个redis服务器。(就是个应用程序而已。) 1.单机模式 我们安装redi,启动服务之后&#xff0c;默认就这个&#xff0c;只有一个redis服务器(…

编译原理笔记(哈工大编译原理)(持续更新)

文章目录 前言概论语言与文法基本概念字母表串字母表与串的联系 文法语言推导和规约句型与句子语言与字母表 文法的分类CFG的分析树 前言 说实话&#xff0c;我不是很想上这门课&#xff0c;确实没什么大用&#xff0c;虽然我觉得这门课学一学也挺好&#xff0c;但是我觉得弄8…

架构师必备项目管理方法-关键路径法

在《架构思维的六要素》中提到成本、规划、需求、维护、人员和质量是要考量的留个维度。咱们在日常工作中多少都会接触一些相关的管理方法&#xff0c;但是似乎是不知道也不影响干活&#xff0c;所以很多人也没有去深究。但实际上很可能知道了做事就更能抓住重点。 关键路径法是…

预测神经胶质瘤基因型的多模态学习

文章目录 Multi-modal learning for predicting the genotype of glioma摘要本文方法多模态数据生成Brain networks construction via self-supervised NNsMulti-modal learning for image, geometrics and brain networksBi-level multi-modal contrastive loss Population gr…

html实现好看的个人介绍,个人主页模板3(附源码)

文章目录 1.设计来源1.1 主界面1.2 关于我界面1.3 教育成就界面1.4 项目演示界面1.5 联系我界面 2.效果和源码2.1 动态效果2.2 源代码2.2 源代码目录 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/131263195 …

新手Maven入门(一)

Mavenue介绍和基本概念 一、什么是Maven1.1 Maven的组成1.2 安装和配置Maven1.2.1 下载1.2.2 安装 二、Maven 的基本概念2.1 标准的目录结构2.2 POM 大纲2.2.1 pom大纲展示 2.3 构件2.3.1 什么是maven的构建 2.4 POM 文件的用例2.5 GAV 坐标 三、依赖 一、什么是Maven Maven 是…

2023年前端面试汇总-计算机网络

1. HTTP协议 1.1. GET和POST的请求的区别 Post 和 Get 是 HTTP 请求的两种方法&#xff0c;其区别如下&#xff1a; 1. 应用场景 GET 请求是一个幂等的请求&#xff0c;一般 Get 请求用于对服务器资源不会产生影响的场景&#xff0c;比如说请求一个网页的资源。而 Post 不是…

如何在Ubuntu上安装MongoDB?

一、Ubuntu安装MongoDB MongoDB安装很简单&#xff0c;无需下载源文件&#xff0c;可以直接用apt-get命令进行安装。 打开终端&#xff0c;输入以下命令 sudo apt-get install mongodb这时装好以后应该会自动运行mongod程序&#xff0c;通过命令查看进程是否已经启动 pgrep …

Spring 实现AOP常见的两种方式(注解或者自定义注解)

第一种 导入AOP相关坐标(依赖冲突解决办法&#xff0c;将依赖中版本号删除&#xff0c;springboot会自动匹配合适的版本 ) <dependencies><!--spring核心依赖&#xff0c;会将spring-aop传递进来--><dependency><groupId>org.springframework</gr…

自动化测试必会之数据驱动测试

数据驱动测试 在实际的测试过程中&#xff0c;我们会发现好几组用例都是相同的操作步骤&#xff0c;只是测试数据的不同&#xff0c;而我们往往需要编写多次用例来进行测试&#xff0c;此时我们可以利用数据驱动测试来简化该种操作。 参数化&#xff1a; 输入数据的不同从而产…

C语言:输入两个升序排列的序列,将两个序列合并为一个有序序列并输出。

题目&#xff1a; 描述 输入两个升序排列的序列&#xff0c;将两个序列合并为一个有序序列并输出。 输入描述&#xff1a; 输入包含三行&#xff0c; 第一行包含两个正整数n, m&#xff0c;用空格分隔。n表示第二行第一个升序序列中数字的个数&#xff0c;m表示第三…

C++ 教程(12)——循环

C 循环 有的时候&#xff0c;可能需要多次执行同一块代码。一般情况下&#xff0c;语句是顺序执行的&#xff1a;函数中的第一个语句先执行&#xff0c;接着是第二个语句&#xff0c;依此类推。 编程语言提供了允许更为复杂的执行路径的多种控制结构。 循环语句允许我们多次…

朋友圈功能合集来咯!定时发朋友圈,查看朋友圈,朋友圈跟圈,一键转发朋友圈,延迟评论

&#x1f30a;发布朋友圈 功能介绍&#xff1a;可使用已登录在系统上的微信号发送朋友圈。支持发送图片、文字、视频和公众号链接等几种类型的内容。 &#xff08;1)朋友圈内容编辑&#xff1a;可以在输入框中输入要发送的文本&#xff0c;并在浮窗中选择表情。上传图片可以点…

【c++11】c++11特性

c11 c11简介列表初始化std::initializer_list autodecltypenullptr 结语 c11简介 从C0x到C11&#xff0c;C标准10年磨一剑&#xff0c;第二个真正意义上的标准珊珊来迟。相比于C98/03&#xff0c;C11则带来了数量可观的变化&#xff0c;其中包含了约140个新特性&#xff0c;以…

QT QTreeView\QTreeWidget控件 使用详解

本文详细的介绍了QTreeView、QTreeWidget控件的各种操作&#xff0c;例如&#xff1a;新建界面、QTreeWidget、QTreeView、控件布局、设置列、设置宽高、设置列表头、设置复选框、设置图标、添加树、删除树、查找树、修改树、设置选中、树排序、事件、信号、槽函数、添加节点、…

【玩转Docker小鲸鱼叭】MacOS系统安装Docker

安装Docker Mac 系统安装 Docker 其实很简单&#xff0c;我们在官方文档下载安装一下就可以了&#xff0c;但是需要注意 Docker 官方建议 MacOS 必须是版本 11 或更高版本&#xff0c;如果版本较低&#xff0c;建议先升级 MacOS 版本。 可以通过左上角的小  图片查看系统版…

浅析Spring-kafka源码——消费者模型的实现

SpringBoot项目中的消费端实现而言,Spring-kafka没有用原生的ConsumerConnector,,而是借助原生client的拉取消息功能做了自己的消费模型的实现,提供了@KafkaListener注解这种方式实现消费。 开发中在使用Spring-kafka时,一般也都是通过使用@KafkaListener注解的方法来实现…