Dubbo Filter机制概述
https://blog.csdn.net/prestigeding/article/details/82085705
从上文可知,在服务的调用或消费端发送请求命令中,Dubbo引入过滤器链机制来实现功能的包装(或扩展)。Dubbo很多功能,例如泛化调用、并发控制等都是基于Filter机制实现的,系统默认的Filter在/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Filter文件中定义,内容如下:
echo=com.alibaba.dubbo.rpc.filter.EchoFilter
generic=com.alibaba.dubbo.rpc.filter.GenericFilter
genericimpl=com.alibaba.dubbo.rpc.filter.GenericImplFilter
token=com.alibaba.dubbo.rpc.filter.TokenFilter
accesslog=com.alibaba.dubbo.rpc.filter.AccessLogFilter
activelimit=com.alibaba.dubbo.rpc.filter.ActiveLimitFilter
classloader=com.alibaba.dubbo.rpc.filter.ClassLoaderFilter
context=com.alibaba.dubbo.rpc.filter.ContextFilter
consumercontext=com.alibaba.dubbo.rpc.filter.ConsumerContextFilter
exception=com.alibaba.dubbo.rpc.filter.ExceptionFilter
executelimit=com.alibaba.dubbo.rpc.filter.ExecuteLimitFilter
deprecated=com.alibaba.dubbo.rpc.filter.DeprecatedFilter
compatible=com.alibaba.dubbo.rpc.filter.CompatibleFilter
timeout=com.alibaba.dubbo.rpc.filter.TimeoutFilter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
以其中一个来说明一下Filter的定义要素:
/**
* EchoInvokerFilter
*/
@Activate(group = Constants.PROVIDER, order = -110000) // @2
public class EchoFilter implements Filter { // @1
@Override
public Result invoke(Invoker<?> invoker, Invocation inv) throws RpcException {
if (inv.getMethodName().equals(Constants.$ECHO) && inv.getArguments() != null && inv.getArguments().length == 1)
return new RpcResult(inv.getArguments()[0]);
return invoker.invoke(inv);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
代码@1:实现com.alibaba.dubbo.rpc.Filter接口。
代码@2:添加Activate,其注解含义如下:
group: 所属组,String[],例如消费端、服务端。
value String[],如果指定该值,只有当消费者或服务提供者URL中包含属性名为value的键值对,该过滤器才处于激活状态。
before:String[],用于指定执行顺序,before指定的过滤器在该过滤器之前执行。
after:string[],用于指定执行顺序,after指定的过滤器在该过滤器之后执行。
order:用户指定顺序,值越小,越先执行。
除了支持默认的过滤器外,Dubbo还支持自定义Filter,可以通过service.filter指定过滤器,多个用英文逗号隔开,其配置方法为:
< dubbo:service ……>
< dubbo:parameter key = “service.filter” value = “filter1,filer2,…”/>
< /dubbo:service>
当然,可以为所有服务提供者设置共用过滤器,其指定方法为:
< dubbo:provider …>
< dubbo:parameter key = “service.filter” value = “filter1,filer2,…”/>
< /dubbo:provider>
消费端自定义过滤器的key为reference.filter,其使用方法在< dubbo:reference/>标签或< dubbo:consumer/>标签下定义属性。
关于自定义Filter的解析代码如下:
ExtensionLoader#getActivateExtension
public List<T> getActivateExtension(URL url, String key, String group) { // @1
String value = url.getParameter(key); // @2
return getActivateExtension(url, value == null || value.length() == 0 ? null : Constants.COMMA_SPLIT_PATTERN.split(value), group); // @3
}
1
2
3
4
代码@1:参数说明。
URL url:服务提供者或服务消费者url。
String key:过滤器属性key,服务提供者固定为:service.filter,服务消费者固定为reference.filter。
String group:服务提供者或服务消费者。
代码@2:从url中获取配置的自定义filter。
代码@3:如果value不为空,则将字符串调用split转换为数组,然后调用getActivateExtension方法,获取符合条件的过滤器。
ExtensionLoader#getActivateExtension
public List<T> getActivateExtension(URL url, String[] values, String group) {
List<T> exts = new ArrayList<T>();
List<String> names = values == null ? new ArrayList<String>(0) : Arrays.asList(values);
if (!names.contains(Constants.REMOVE_VALUE_PREFIX + Constants.DEFAULT_KEY)) { // @1
getExtensionClasses(); // @2
for (Map.Entry<String, Activate> entry : cachedActivates.entrySet()) {
String name = entry.getKey();
Activate activate = entry.getValue();
if (isMatchGroup(group, activate.group())) { // @3
T ext = getExtension(name);
if (!names.contains(name)
&& !names.contains(Constants.REMOVE_VALUE_PREFIX + name) // @4
&& isActive(activate, url)) { // @5
exts.add(ext);
}
}
}
Collections.sort(exts, ActivateComparator.COMPARATOR);
}
List<T> usrs = new ArrayList<T>();
for (int i = 0; i < names.size(); i++) { // @6
String name = names.get(i);
if (!name.startsWith(Constants.REMOVE_VALUE_PREFIX)
&& !names.contains(Constants.REMOVE_VALUE_PREFIX + name)) {
if (Constants.DEFAULT_KEY.equals(name)) {
if (!usrs.isEmpty()) {
exts.addAll(0, usrs);
usrs.clear();
}
} else {
T ext = getExtension(name);
usrs.add(ext);
}
}
}
if (!usrs.isEmpty()) {
exts.addAll(usrs);
}
return exts;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
代码@1:如果配置的service.filter或referecnce.filter包含了-default,表示禁用系统默认提供的一系列过滤器。
代码@2:如果不禁用系统默认过滤器链,则首先加载所有默认过滤器。
代码@3:根据group刷选出适配的过滤器。
代码@4:也可以对单个filter进行禁用,其方法是-过滤器名称的方式。例如如想禁用AccessLogFilter,则可以通过-accesslog方式禁用。-key,key为/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.r
pc.Filter中定义的key。
代码@5:判断过滤器是否激活,其逻辑是如果Filter上的@Activate注解value值不为空,则需要判断url中是否包含键为value的属性对,存在则启用,不存在则不启用。
代码@6:加载用户自定义的Filter,也即是service.filter或reference.filter指定的过滤器。
综上所述,Dubbo提供了过滤器机制,在真实服务被调用前提供扩展点。Filter机制就简单介绍到这里了,从下文开始会重点分析Dubbo服务提供的核心Filter。
如果需要自定过滤器,需要在自定的工程中META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Filter文件中注册。
本文就介绍到这里了,从下篇开始将会根据Dubbo的功能特性来详细分析其实现过程,其本质都是各种Dubbo 过滤器器。
————————————————
版权声明:本文为CSDN博主「唯有坚持不懈」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/prestigeding/article/details/82085705
Dubbo Filter机制概述的更多相关文章
- 基于SLF4J的MDC机制和Dubbo的Filter机制,实现分布式系统的日志全链路追踪
原文链接:基于SLF4J的MDC机制和Dubbo的Filter机制,实现分布式系统的日志全链路追踪 一.日志系统 1.日志框架 在每个系统应用中,我们都会使用日志系统,主要是为了记录必要的信息和方便排 ...
- Android广播机制概述
1.Android广播机制概述 Android广播分为两个方面:广播发送者和广播接收者,通常情况下,BroadcastReceiver指的就是广播接收者(广播接收器).广播作为Android组件间的通 ...
- Dubbo SPI 机制源码分析(基于2.7.7)
Dubbo SPI 机制涉及到 @SPI.@Adaptive.@Activate 三个注解,ExtensionLoader 作为 Dubbo SPI 机制的核心负责加载和管理扩展点及其实现.本文以 E ...
- SQL Server 内存中OLTP内部机制概述(四)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- SQL Server 内存中OLTP内部机制概述(三)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- SQL Server 内存中OLTP内部机制概述(二)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- SQL Server 内存中OLTP内部机制概述(一)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<SQL Server In-Memory ...
- VS2010/MFC编程入门之五(MFC消息映射机制概述)
VS2010/MFC编程入门之五(MFC消息映射机制概述)-软件开发-鸡啄米 http://www.jizhuomi.com/software/147.html 上一讲鸡啄米为大家简单分析了MFC应用 ...
- JVM垃圾回收机制概述
JVM垃圾回收机制概述 1.定义 是指JVM用于释放那些不再使用的对象所占用的内存. 2.方式 2.1引用计数(早期) 当引用程序创建引用以及引用超出范围时,JVM必须适当增减引用数.当某个对象的引用 ...
随机推荐
- Vue学习之监听methods、watch及computed比较小结(十一)
一.三者之间的对比: 1.methods方法表示一个具体的操作,主要书写业务逻辑: 2.watch:一个对象,键是需要观察的表达式,值是对应回调函数.主要用来监听某些特定数据的变化,从而进行某些具体业 ...
- 英语SouthRedAgate南红玛瑙
南红玛瑙(SouthRedAgate)是玛瑙的一个种类,古称”赤玉”,质地细腻油润,是中国独有的品种.由于产量稀少,老南红玛瑙价格急剧上升.南红玛瑙曾被古人用之入药,养心养血. 现在的南红玛瑙已经和和 ...
- Java集合学习(7):ArrayList
一.概述 ArrayList可以理解为动态数组,就是Array的复杂版本.与Java中的数组相比,它的容量能动态增长.ArrayList是List接口的可变数组的实现.实现了所有可选列表操作,并允许包 ...
- 摘jmeter安装之后如何汉化
下载完成后打开bin文件,选择jmeter.properties打开,搜索language,修改成zh_CN,汉化jmeter,记得去掉前面的#号,然后保存,修改完配置文件后需要重启jmeter 用的 ...
- zabbix--远程执行命令
zabbix 远程执行命令 重启应用 服务器 使用远程执行命令可以在某些时候帮我做一些事情,达到轻量级的自动化,比如当 nginx.mysql.php.redis.tomcat.等等应用挂掉时帮我们自 ...
- SqlServer中的更新锁(UPDLOCK和READPAST)
UPDLOCK和READPAST,通过UPDLOCK和READPAST的结合我们能够解决许多问题,比如我当前项目中对于更新预约人数,则用到了UPDLOCK和READPAST,因为考虑到并发如果固定预约 ...
- Unity 渲染教程余下
可能来源于(英文):https://catlikecoding.com/unity/tutorials/ Unity渲染教程(一):矩阵 http://gad.qq.com/pro ...
- PHP中的匿名类
许久不练,要写起来. <?php //匿名类, 同样可以使用继承,接口,特性 //内部匿名类使用外部类的方法和属性,通过继承或构造方法传参 $object = new class { publi ...
- HDU6625: three arrays (字典树处理xor)
题意:给出A数组,B数组,你可以对A和B分别进行重排列,使得C[i]=A[i]^B[i]的字典序最小. 思路:对于这类题,显然需要建立字典树,然后某种形式取分治,或者贪心. 假设现在有了两颗字典树A ...
- linux 用户操作命令
今日思语:看到优秀的人还那么努力,你是否会眼馋~ linux系统上经常会对用户进行一些相关操作,像新增.修改.删除用户等操作. 1.新增用户 useradd 选项 用户 参数说明: • 选项: • - ...