dubbo过滤器的原理是什么?
1 个回答
我依旧待人真诚,但不寄予厚望。姜尚### **Dubbo 过滤器(Filter)的原理** Dubbo 过滤器(Filter)是一种 **责任链模式(Chain of Responsibility)** 的 AOP 机制,允许在 **服务调用前后** 对请求进行 **拦截、修改或增强**,如日志记录、权限校验、限流、监控等。 ## **1. Filter 的调用流程** Dubbo 在 **服务提供方(Provider)** 和 **服务消费方(Consumer)** 两端都支持 `Filter`,其工作原理如下: ### **① Consumer 端 Filter 执行流程** 当客户端调用 Dubbo 服务时: 1. `Invoker` 代表 **真正的服务调用者**。 2. `Filter` 通过 **责任链模式** 依次拦截请求,执行逻辑(如鉴权、日志、限流等)。 3. **最后一个 `Invoker` 调用远程服务**,发送请求到 Provider。 4. **响应结果** 依次经过 `Filter` 处理后返回。 ```plaintext Consumer 调用链: 用户代码 -> Filter1 -> Filter2 -> Filter3 -> Invoker(真正的调用) -> 远程服务 ``` ### **② Provider 端 Filter 执行流程** 当 Dubbo 服务端接收到请求时: 1. 依次通过 Filter 处理请求(如日志记录、黑名单、限流)。 2. **最后一个 `Invoker` 负责调用真正的业务逻辑**,返回结果。 3. 结果依次经过 Filter 处理后返回给 Consumer。 ```plaintext Provider 调用链: 远程请求 -> FilterA -> FilterB -> FilterC -> Invoker(业务逻辑) -> 返回响应 ``` ## **2. Filter 机制的核心组件** ### **① Filter 接口** Dubbo 提供 `org.apache.dubbo.rpc.Filter` 接口,定义了 `invoke` 方法: ```java @SPI public interface Filter { Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException; } ``` - `invoker`:实际执行调用的 `Invoker`。 - `invocation`:调用信息(方法名、参数、上下文等)。 - `Result`:调用结果。 ### **② Dubbo 默认的 Filter** Dubbo 自带了多个 `Filter`,例如: | **Filter 名称** | **作用** | |--------------------|------------------------| | `EchoFilter` | 心跳检测 | | `ExceptionFilter` | 统一异常处理,防止敏感信息泄露 | | `AccessLogFilter` | 记录访问日志 | | `MetricsFilter` | 统计调用数据 | | `TpsLimitFilter` | 限流控制 | ### **③ SPI 机制自动加载 Filter** Dubbo 使用 **SPI(Service Provider Interface)机制** 自动加载 `Filter`: - 过滤器配置文件 `META-INF/dubbo/org.apache.dubbo.rpc.Filter` - 配置多个 `Filter` 时,Dubbo 通过 **责任链模式** 依次执行 ```plaintext META-INF/dubbo/org.apache.dubbo.rpc.Filter: customFilter=com.example.CustomFilter ``` ## **3. Dubbo Filter 实现示例** ### **① 自定义日志记录 Filter** ```java @Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER}) public class LogFilter implements Filter { @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { System.out.println("请求方法:" + invocation.getMethodName()); // 调用下一个 Filter 或 Invoker Result result = invoker.invoke(invocation); System.out.println("返回结果:" + result.getValue()); return result; } } ``` **说明**: - `@Activate` 注解表示 **自动生效**,`group` 指定是 **Provider 端还是 Consumer 端**。 - `invoker.invoke(invocation)` 继续调用下一个 `Filter` 或 `Invoker`。 - `Result` 代表 RPC 调用的返回值。 ### **② 通过 XML 启用自定义 Filter** ```xml <dubbo:protocol name="dubbo" filter="logFilter" /> ``` ### **③ 通过 Java 代码启用** ```java ProtocolConfig protocolConfig = new ProtocolConfig(); protocolConfig.setName("dubbo"); protocolConfig.setFilter("logFilter"); ``` ## **4. 关键特性** ### **① 责任链模式** 多个 `Filter` 通过 **链式调用** 依次执行,每个 `Filter` 处理后都可以: - 继续调用 `invoker.invoke(invocation)` - 或者 **终止链条**(如权限校验失败) ```java public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { System.out.println("执行前"); Result result = invoker.invoke(invocation); System.out.println("执行后"); return result; } ``` ### **② `@Activate` 自动激活** `@Activate` 支持 **自动激活**,可以通过 `group` 指定 **Consumer 端 / Provider 端**: ```java @Activate(group = {CommonConstants.CONSUMER}) // 仅在 Consumer 端生效 ``` ### **③ 结合 `SPI` 机制动态扩展** Dubbo 通过 `SPI` 机制自动加载 `Filter`,可以在 `META-INF/dubbo/org.apache.dubbo.rpc.Filter` 配置扩展点,无需修改源码。 ## **5. 总结** 1. **Dubbo 过滤器是基于责任链模式的 AOP 拦截机制**,可在 RPC 调用前后拦截请求,进行 **日志、权限、监控、限流** 等操作。 2. **`Filter` 通过 SPI 机制动态加载**,可以灵活扩展。 3. **`@Activate` 可自动生效**,无需额外配置。 4. **多个 `Filter` 组合使用**,按照责任链模式 **依次执行**,最终调用 `Invoker` 进行远程调用。 Dubbo 过滤器是 **非侵入式增强 Dubbo 功能** 的重要机制,适用于 **日志、监控、权限、限流等场景**。编辑于 2025-02-15 07:08 •IP属地 美国举报评论收藏
公众号进入网站体验更佳

