详解如何自定义Dubbo Filter(含dubbo2.7.X及以上版本和2.6.X及以下版本两种写法)

一、前言

前一段时间做了一个日志审计模块,其中会对HTTP调用、Dubbo接口之前做链路追踪,针对HTTP调用Dubbo接口、Dubbo接口中调用Dubbo接口的场景采用自定义Dubbo Filter(Provider/Consumer)的方式传递链路入口信息、操作用户、链路ID。其中牵扯到Dubbo RpcContext的使用,对着RpcContext以及遇到的坑,在下一篇文章中讨论;

二、自定义Filter

官方文档https://dubbo.apache.org/zh/docsv2.7/dev/impls/filter/

我们注意到在https://mvnrepository.com/artifact/org.apache.dubbo/dubbo中,org.apache.dubbo组织下的dubbo版本最低只有2.7.0

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.7.0</version>
</dependency>

那么dubbo2.7.0以下的版本呢?在mvnrepository中搜索dubbo,我们可以看到还存在一个com.alibaba组织下的dubbo;
请添加图片描述
细想一下,dubbo最开始是没开源的;看来dubbo2.7.0之下的版本应该依赖都在com.alibaba组织下:
请添加图片描述

谁闲着没事还会去看老版本呢?巧了老项目用dubbo2.6.X、dubbo2.5.X都太正常了;
博主就遇到了,业务方引入我的日志审计SDK说,说用不了;博主作为一个新程序员,学的基本都是新版本、新技术,也只有通过老项目才会去了解老版本;在此总结一下。

1、最新版本自定义Filter(dubbo2.7.X及以上版本)

1)实现Filter
package com.saint.dubbo;

import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

/**
 * @author Saint
 */
@Slf4j
@Activate(group = {CommonConstants.PROVIDER})
public class DubboProviderFilter implements Filter {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

        // 服务端从dubbo上下文中取出traceContext信息
        String jsonStr = null;
        ......
        return invoker.invoke(invocation);

    }
}
2)Filter实现类映射到Spring容器

resources目录下增加META-INF/dubbo/org.apache.dubbo.rpc.Filter文件;
内容如下:

providerFilter=com.saint.dubbo.DubboProviderFilter

其中:

  • providerFilter 为将要在dubbo配置文件或yml文件中配置的Filter名,想写啥写啥;
  • com.saint.dubbo.DubboProviderFilter为我们自定义的Filter类;

假如我要写多个自定义的Filter呢?官方这里并没有说,很多博文也没说;其实再加一行就行。

providerFilter=com.saint.dubbo.DubboProviderFilter
consumerFilter=com.saint.dubbo.DubboConsumerFilter
3)Filter实现类关联到Dubbo Consumer / Provider

这里有两种方式(推荐使用第二种):

1> 在dubbo的xml配置文件中添加如下配置:

<dubbo:provider filter="providerFilter" />
<dubbo:consumer filter="consumerFilter" />

2> 在property/yaml配置文件中的添加如下配置:

dubbo:
  consumer:
    filter: consumerFilter
  provider:
    filter: providerFilter

如果针对一个consumer或provider有多个filter呢?以英文,隔开即可;

dubbo:
  consumer:
    filter: consumerFilter,userConsumerFilter
  provider:
    filter: providerFilter

2、未开源前的版本自定义Filter(dubbo2.6.X及以下版本)

Dubbo2.6.X及以下版本Dubbo2.7.X及以上版本 在代码实现上的唯一区别点在于实现Filter的方式;Filter实现类映射到Spring容器的方式 和 Filter实现类关联到Dubbo Consumer / Provider的方式均一样。

1)实现Filter
package com.saint.dubbo;

import lombok.extern.slf4j.Slf4j;
import com.alibaba.dubbo.common.Constants;
import com.alibaba.dubbo.common.extension.Activate;
import com.alibaba.dubbo.rpc.*;

/**
 * @author Saint
 */
@Slf4j
@Activate(group = {Constants.CONSUMER})
public class DubboProviderFilter implements Filter {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

        // 服务端从dubbo上下文中取出traceContext信息
        String jsonStr = null;
        ......
        return invoker.invoke(invocation);

    }
}

这里和2.7.X及以上版本的区别如下:

  • 主要是引的包不一样;Dubbo2.6.X及以下版本使用的是com.alibaba.dubbo包,而Dubbo2.7.X及以上版本使用的是org.apache.dubbo包;
  • 其次,指定@Activate的group属性时,常量类不一样;Dubbo2.6.X及以下版本使用Constants常量类,Dubbo2.7.X及以上版本使用CommonConstants接口;
    请添加图片描述
    请添加图片描述

如下操作和Dubbo2.7.X一毛一样!!!

2)Filter实现类映射到Spring容器

resources目录下增加META-INF/dubbo/org.apache.dubbo.rpc.Filter文件;
内容如下:

providerFilter=com.saint.dubbo.DubboProviderFilter

其中:

  • providerFilter 为将要在dubbo配置文件或yml文件中配置的Filter名,想写啥写啥;
  • com.saint.dubbo.DubboProviderFilter为我们自定义的Filter类;

假如我要写多个自定义的Filter呢?官方这里并没有说,很多博文也没说;其实再加一行就行。

providerFilter=com.saint.dubbo.DubboProviderFilter
consumerFilter=com.saint.dubbo.DubboConsumerFilter
3)Filter实现类关联到Dubbo Consumer / Provider

这里有两种方式(推荐使用第二种):

1> 在dubbo的xml配置文件中添加如下配置:

<dubbo:provider filter="providerFilter" />
<dubbo:consumer filter="consumerFilter" />

2> 在property/yaml配置文件中的添加如下配置:

dubbo:
  consumer:
    filter: consumerFilter
  provider:
    filter: providerFilter

如果针对一个consumer或provider有多个filter呢?以英文,隔开即可;

dubbo:
  consumer:
    filter: consumerFilter,userConsumerFilter
  provider:
    filter: providerFilter

三、总结

dubbo之所以有两种实现方式的根本原因,在于2018年2月份dubbo开源(阿里捐献给了Apache)后group由com.alibaba变为了org.apache;此外还有一些代码上的优化:比如 Dubbo2.6.X及以下版本常量采用Class类的静态常量维护,而Dubbo2.7.X及以上版本常量采用Interface接口中维护常量。

希望这边文章对同样维护老项目的兄弟有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秃秃爱健身

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值