深度解析dubbo过滤器Filter

本文基于dubbo v2.6.1

阅读本篇文章需要有dubbo 服务暴露,服务引用,dubbo spi 机制的基础,如果没有,还请移步《深度解析dubbo源码系列》将这三部分内容吃透,本文在讲解的过程中尽量上下联系起来,造成不适还请谅解。

文章目录

      • 1. 介绍
      • 2. Filter链形成时机
        • 2.1 Filter接口
        • 2.2 服务提供者
        • 2.3 服务调用者
        • 2.4 ProtocolFilterWrapper
        • 2.5 获取filters
        • 2.6 服务提供者filters
        • 2.7 服务消费者filters

1. 介绍

当我们使用服务提供者调用服务提供者的时候,会经过一系列的Filter链,注意,这个Filter链在服务提供者端有,在服务调用者端也是有的,可以根据下面这个图理解下,大体是这个样子的。
深度解析dubbo过滤器Filter_第1张图片

2. Filter链形成时机

2.1 Filter接口

首先我们先认识一下Filter接口
深度解析dubbo过滤器Filter_第2张图片
可以看到Filter接口是基于dubbo spi 进行扩展的,就一个invoke抽象方法。我们在注释中也可以了解到可以在invoker.invoke()前添加自己的业务逻辑作为前置filter,也可以在后面添加自己的逻辑作为后置filter。

2.2 服务提供者

在服务提供者端,当我们服务启动进行服务暴露的时候,com.alibaba.dubbo.config.ServiceConfig#doExportUrlsFor1Protocol 方法中有行Exporter exporter = protocol.export(wrapperInvoker);,其实真实调用的那个protocol是根据dubbo spi 自适应出来的,然后这里真实调用RegistryProtocol,有根据dubbo spi 对实现类的setter注入与wrapper包装,这个RegistryProtocol 对象外层就会包装上QosProtocolWrapper,ProtocolFilterWrapper,ProtocolListenerWrapper ,也就是在调用的时候会先调用到这三个包装类上面,最后才会盗用到RegistryProtocol ,想了解QosProtocolWrapper的可以参考下《深度解析dubbo在线运维Qos》,这里就不再赘述,我们这里主要关心下ProtocolFilterWrapper的export方法
在这里插入图片描述
这里这个protocol正好是registry ,然后就走了if语句中。
接着就到RegistryProtocol 的export方法

第一句调用了doLocalExport方法进行服务暴露
深度解析dubbo过滤器Filter_第3张图片
这里就是从bounds这个缓存中获取exporter,如果没有就创建,然后加到缓存中, 我们着重看下画红框那行,其实这个Protocol根据自适应的规则,就是DubboProtocol了,它跟RegistryProtocol 一样,也是被wrapper包装了,然而不一样的是在ProtocolFilterWrapper 的export方法中走的是buildInvokerChain方法,这个方法就是生成Filter链的,这个我们在后面章节,对于服务暴露不明朗的可以看下我远程暴露的文章。

2.3 服务调用者

服务调用者其实跟服务提供者的生成链的时机差不多,当注册中心的providers,configurators,routers发生变化的时候,就会通知RegistryDirectory的notify方法,然后就需要将url转换成invoker,在转换invoker的时候,有这么一行代码(出自com.alibaba.dubbo.registry.integration.RegistryDirectory#toInvokers)
在这里插入图片描述
这个protocol也是根据场景自适应出来的,这里是DubboProtocol,然后根据dubbo spi 的wrapper机制,它会被包上上面说的那三个类,
我们看下ProtocolFilterWrapper的refer方法。
在这里插入图片描述
这里也是没有进if判断,而是走了这个buildInvokerChain方法,跟服务暴露一样,接下来我们就来看下这个buildInvokerChain 方法的实现。

2.4 ProtocolFilterWrapper

我们在上面两个小节已经将ProtocolFilterWrapper 的refer与export方法讲解了,接下来就是buildInvokerChain 方法,我们重点看下子
深度解析dubbo过滤器Filter_第4张图片
首先看下参数:
invoker : 在服务调用者端能通过invoker发起远程调用
在服务提供者端能通过 invoker 调用真实的service(也就是是那个接口实现类)方法
key : 在调用者端是reference.filter
在提供者端是service.filter
group: 在调用端是 consumer
在提供者端是 provider
接着往下看,根据dubbo spi 自动激活规则,能够获取到某些条件下的实现类集合,这里就是获取filters。这里不理解的可以看下《深度解析dubbo扩展技术dubbo spi(自动激活实现)》,我在2.5小节里会详细解释。
接着就是倒着遍历,这里不好理解,我画了张图
深度解析dubbo过滤器Filter_第5张图片
调用的时候就是从上面的那个invoker对象调用下来,然后到filter,然后又到invoker,又到filter,直到真实的那个invoker,其中,filter在list中下标越大的越靠里,也就是在调用的时候这个优先级就越低。
这是invoke方法的调用流程,你要是其他方法的话直接就是调用的真实invoker的。

2.5 获取filters

我们这边稍微讲一下获取filter列表,咱们这边以调用者端为例子

List<Filter> filters = ExtensionLoader.getExtensionLoader(Filter.class).getActivateExtension(invoker.getUrl(), key, group);

getActivateExtension 方法传入了一个url,key就是reference.filter ,group是 consumer,我们看下getActivateExtension 方法,
在这里插入图片描述
根据key从url中获取参数值,这个参数值我们可以配置,比如说我们不想激活某个filter,就可以在filter名字前面加个“-”
然后调用重载方法getActivateExtension(),我们先看getActivateExtension 的前半部分
深度解析dubbo过滤器Filter_第6张图片
将你配置的用","分割了然后设置到names中,如果 names里面不包含“-default”,就调用getExtensionClasses 加载扩展class,其实这个就是将Filter的扩展实现类全找出来(这个是有条件的,就是要遵循dubbo spi的规则配置)然后带有@Activate注解(这个注解就是咱们自动激活的注解)的实现类就会被安排在cachedActivates 缓存map中
深度解析dubbo过滤器Filter_第7张图片
接着就是for循环了,遍历cachedActivates这个map,获得Activate 注解里面的内容,进行group的匹配,接着就是判断你设置的names里面不存在这个缓存的name,然后也不存在带“-”的name,就添加到exts集合中,接着就是按照排序规则排序了,我们接着看下半部分
深度解析dubbo过滤器Filter_第8张图片
遍历names 集合,也就是你配置的那个, name不是“-”开头,然后names中也不包含“-”name的,如果name=default,usr不是空的,就把usr里面的添加到exts的前头,如果name!=default 获取对应name的扩展,添加到usrs中,到最后就是usrs不是空的话就添加到exts中。
这里我们再说一下这个排序规则ActivateComparator
先是按照两个对象是不是null来判断
深度解析dubbo过滤器Filter_第9张图片
接着就是@Activate 里面的before与after 来排序
深度解析dubbo过滤器Filter_第10张图片
最后才是按照order大小来排序
在这里插入图片描述
好了,到这获取filters咱们就讲解完成了。

2.6 服务提供者filters

深度解析dubbo过滤器Filter_第11张图片
这是dubbo v2.6 里面服务提供者的filters,调用顺序是这个样子的: echo->classloader->generic->context->trace->timeout->moniter->exception

2.7 服务消费者filters

在这里插入图片描述
这是dubbo v2.6 里面服务调用者的filters,调用顺序是这个样子的:ConsumerContext->Future->Monitor

你可能感兴趣的:(深度解析dubbo源码,dubbo,filter,dubbo,过滤器,filter,chain)