Adaptive 功能详解
功能概述
Dubbo 中的 Adaptive 功能是一种动态适配机制,它能够根据运行时条件自动选择并加载最合适的扩展点实现。该功能的核心是解决在分布式系统中如何根据不同的运行环境和配置动态切换具体实现类的问题。
核心机制
-
动态选择机制:
- 通过
getAdaptiveExtension()方法统一封装指定接口对应的所有扩展点 - 采用装饰器模式对扩展点进行包装
- 运行时根据URL参数动态决定使用哪个具体实现
- 通过
-
URL驱动机制:
- Dubbo中所有注册信息都通过URL形式处理
- URL格式示例:
dubbo://192.168.1.1:20880/com.service.DemoService?timeout=3000&loadbalance=random
典型应用场景
- 协议选择:根据URL中的protocol参数自动选择协议实现
- 集群容错:根据cluster参数选择容错策略
- 负载均衡:根据loadbalance参数选择算法
代码示例
// 通过 getAdaptiveExtension 来提供一个统一的类来对所有扩展点提供支持
final WzkHelloService adaptiveExtension =
ExtensionLoader.getExtensionLoader(WzkHelloService.class).getAdaptiveExtension();
System.out.println(adaptiveExtension.sayHello(url));
拦截操作
Dubbo Filter 机制详解
基本工作原理
Dubbo 的 Filter 机制是专门为服务提供方(Provider)和消费方(Consumer)的调用过程设计的拦截器链。每次远程方法调用时,注册的 Filter 都会按照特定顺序被执行,形成完整的调用链。
典型应用场景
- 访问控制:实现 IP 白名单/黑名单过滤
- 监控统计:记录调用耗时、成功率等指标
- 日志记录:记录请求/响应数据用于调试
- 参数校验:对输入参数进行合法性校验
- 限流熔断:实现服务的流量控制和熔断保护
实现方式示例
public class WhitelistFilter implements Filter {
private List<String> allowedIps = Arrays.asList("192.168.1.1", "10.0.0.1");
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
String clientIp = RpcContext.getContext().getRemoteHost();
if (!allowedIps.contains(clientIp)) {
throw new RpcException("IP " + clientIp + " is not allowed");
}
return invoker.invoke(invocation);
}
}
执行流程
Dubbo Filter 的执行遵循以下顺序:
- 消费方 Filter 链(由后向前)
- 网络传输
- 提供方 Filter 链(由前向后)
- 实际服务方法调用
- 响应沿原路径返回
自定义拦截
@Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER}, order = -1000)
public class WzkLogFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
System.out.println("[自定义WzkLogFilter 之前]" + invocation.getMethodName());
Result result = invoker.invoke(invocation);
System.out.println("[自定义WzkLogFilter 之后]" + invocation.getMethodName());
return result;
}
}
总结
Adaptive 与 Filter 的结合,是 Dubbo 高可插拔架构设计的关键体现。开发者只需实现 Filter 接口并通过 SPI 和 @Activate 注解进行注册,即可实现功能增强。这种设计让 Dubbo 具备了极高的灵活性和可扩展性。