Dubbo——过滤器概述

Dubbo过滤器概述

Dubbo中的过滤器和Web应用中的过滤器的概念是一样的,提供了在服务调用前后插入自定义逻辑的途径。过滤器是整个Dubbo框架中非常重要的组成部分,Dubbo中很多功能都是基于过滤器扩展而来的。过滤器提供了服务提供者和消费者调用过程的拦截,即每次都执行RPC调用的时候,对应的过滤器都会生效。虽然过滤器的功能强大,但由于每次调用时都会执行,因此在使用的时候需要注意它对性能的影响。

过滤器的使用
  • 一种方式是使用@Active注解默认启用;
  • 一种方式是在配置文件中配置;
<!-- 消费方调用过程拦截 -->
<dubbo:reference filter="xxx, yyy" />

<!-- 消费方调用过程默认拦截器,将拦截所有reference -->
<dubbo:consumer filter="xxx, yyy" />

<!-- 服务提供方调用过程拦截 -->
<dubbo:service filter="xxx, yyy" />

<!-- 服务提供方调用过程默认拦截器,将拦截所有service -->
<dubbo:provider filter="xxx, yyy" />

配置上的“潜规则”:

  1. 过滤器顺序:

    • 用户自定义的过滤器的顺序默认会在框架内置过滤器之后,可以使用filter="xxx, default"这种配置方式让自定义的过滤器顺序靠前。
    • 我们在配置filter="xxx, yyy"时,写在前面的xxx会比yyy的顺序要靠前。
  2. 剔除过滤器。对于一些默认的过滤器或自动激活的过滤器,有些方法不想使用这些过滤器,可以使用"-"加过滤器名称来过滤,如filter="-xxFilter"会让xxFilter不生效。如果不想使用所有默认启用的过滤器,则可以配置filter="-default"来进行剔除。

  3. 过滤器的叠加。如果服务提供者、消费者端都配置了过滤器,则两边的过滤器不会相互覆盖,而是互相叠加,都会生效。如果需要覆盖,则可以在消费方使用"-"的方式剔除对应的过滤器。

过滤器的总体结构

在这里插入图片描述

所有的内置过滤器中除了CompatibleFilter特别突出,只继承了Filter接口,既不会被默认激活,其他的内置过滤器都使用了Activate注解,即默认被激活。Filter接口上有@SPI注解,说明过滤器是一个扩展点,用户可以基于这个扩展点接口实现自己的过滤器。

所有的过滤器会被分为消费者和服务提供者两种类型,消费者类型的过滤器只会在服务引用时被加入Inoker,服务提供者类型的过滤器只会在服务暴露的时候被加入对应的Invoker。MonitorFilter比较特殊,它会同时在暴露和引用被加入Invoker。

过滤器名作用使用方
AccessLogFilter打印每一次请求的访问日志。如果需要访问的日志只出现在指定的appender中,则可以在log的配置文件中配置additivity服务提供者
ActiveLimitFilter用于限制消费者端对服务的最大并行调用数消费者
ExecuteLimitFilter同上,用于限制服务端的最大并行调用数」服务提供者
ClassLoaderFilter用于切换不同线程的类加载器,服务调用完成后会还原回去服务提供者
CompatibleFilter用户使返回值与调用程序的对象版本兼容,默认不启用。如果启用,则会把JSON或fastjson类型的返回值转换为Map类型;如果返回类型和本地接口中定义的不同,则会做POJO的转换-
ConsumerContextFilter为消费者把一些上下文信息设置到当前线程的RpcContext对象中,包括invocation、localhost、remote host等消费者
ContextFilter同上,但是为服务提供者服务服务提供者
DeprecatedFilter如果调用的方法被标记位已弃用,那么DeprecatedFilter将记录一个错误消息消费者
EchoFilter用于echo测试服务提供者
ExceptionFilter用于统一的异常处理,防止出现序列化失败服务提供者
GenericFilter用于服务提供者端,实现泛化调用,实现序列化的检查和处理服务提供者
GenericImplFilter同上,但用于消费者端消费者
TimeoutFilter如果某些服务调用超时,则自动记录告警日志服务提供者
TokenFilter服务提供者下令发牌给消费者,通常用于防止消费者绕过注册中心直接调用服务提供者服务提供者
TpsLimitFilter用于服务端的限流,注意与ExecuteLimitFilter消费者
FutureFilter在发起invoke或得到返回值、出现异常的时候触发回调事件消费者
TraceFilterTrace指令的使用服务提供者
MonitorFilter监控并统计所有的接口的调用情况,如成功、失败、耗时。后续DubboMonitor会定时把该过滤器收集的数据发送到Dubbo-Monitor服务上服务提供者+消费者

每个过滤器的使用方不一样,有的是服务提供者使用,有的是消费者使用。Dubbo是如何保证服务提供者不会使用消费者的过滤器的呢?答案就在@Activate注解上,该注解可以设置过滤器激活的条件和顺序,如@Activate(group = Constants.PROVIDER, order = -110000)表示在服务提供端扩展点实现才有效,并且过滤器的顺序是 -110000.

过滤器初始化的实现原理

服务的暴露与引用会使用Protocol层,而ProtocolFilterWrapper包装类则实现了过滤器链的组装。在服务的暴露与引用过程中,会使用ProtocolFilterWrapper#buildInvokerChain方法组装整个过滤器链:

在这里插入图片描述

buildInvokerChain方法构造调用链的步骤:

  1. 获取并遍历所有过滤器。通过ExtensionLoader#getActivateExtension方法获取所有的过滤器并遍历。
  2. 使用装饰器模式,增强原有Invoker,组装过滤器链。使用装饰器模式,像俄罗斯套娃一样,把过滤器一个又一个套到Invoker上。

在这里插入图片描述

为什么要倒排遍历呢?

因为是通过从里到外构造匿名类的方式构造Invoekr的,所以只有倒排,最外层的Invoker才能是第一个过滤器。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Dubbo服务过滤器可以用于在Dubbo服务调用的过程中对请求和响应进行预处理和后处理,例如权限控制、日志记录、统计信息等。在Dubbo中,可以通过配置<provider>或<consumer>标签下的<filter>元素来添加服务过滤器。具体的配置方法如下: 1. 创建一个服务过滤器类,实现org.apache.dubbo.common.extension.Activate接口,并重写filter方法。例如: ```java @Activate(group = "provider") public class MyFilter implements Filter { @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { // 在这里添加过滤器的逻辑 return invoker.invoke(invocation); } } ``` 2. 在服务提供者或服务消费者的配置文件中,添加<filter>元素来引用服务过滤器。例如: ```xml <!-- 服务提供者配置 --> <dubbo:service interface="com.example.SomeService" ref="someService"> <dubbo:method name="someMethod" timeout="5000"> <dubbo:filter ref="myFilter" /> </dubbo:method> </dubbo:service> <!-- 服务消费者配置 --> <dubbo:reference id="someService" interface="com.example.SomeService"> <dubbo:method name="someMethod" timeout="5000"> <dubbo:filter ref="myFilter" /> </dubbo:method> </dubbo:reference> ``` 注意,<filter>元素必须放在<method>元素内部,以便对每个方法都应用过滤器。如果想要对所有方法都应用过滤器,则可以将<filter>元素放在<service>或<reference>元素内部。另外,如果服务过滤器需要传递参数,则可以通过<parameter>元素来配置。例如: ```xml <dubbo:filter ref="myFilter"> <dubbo:parameter key="param1" value="value1" /> <dubbo:parameter key="param2" value="value2" /> </dubbo:filter> ``` 在服务过滤器中可以通过调用invocation.getAttachment(key)方法来获取这些参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值