dubbo 2.7.7 配置 cluster 无效
问题描述
dubbo 2.7.7 消费者、生产者配置 cluster 均无效。消费者调用超时时,依然走的是 failover 的逻辑。
基本描述
dubbo 版本 2.7.7
生产者:2 个
消费者配置
@DubboReference(version = "1.0.0", cluster = "failfast")
TestApiService testApiService;
@GetMapping("/sayHello")
public Object sayHello(String name) {
String hello = testApiService.sayHello(name);
return hello;
}
生产者配置
@DubboService(version = "1.0.0", interfaceClass = TestApiService.class, cluster = "failfast")
public class TestApiServiceImpl implements TestApiService {
public String sayHello(String name) {
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("我是 provider, 我被调用了");
return name + " say hello";
}
}
已经做过的尝试
- debug 进去,看到向 zk 注册的 cluster 确实是 failfast,但是走的还是 failover 逻辑
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
debug 了一下午,最后得出的结论是 dubbo 2.7.7 有 bug。论证过程如下。
先说 2.7.7 为什么不能按照我们的配置加载对应的
Cluster
,再说 2.7.8 如何解决这个 bug 的。
2.7.7 流程
1、dubbo 如何根据你的配置文件加载对应的 Cluster?
源码位置:
RegistryProtocol#doRefer()
Cluster
是一个接口,dubbo 会动态的生成Cluster$Adaptive
类。通过该类生成对应的Cluster
接下来把断点打到
AdaptiveClassCodeGenerator#generateMethod()
AdaptiveClassCodeGenerator#generate()
dubbo 会帮我们生成以下类。
从生成的类代码会发现,会从
org.apache.dubbo.common.URL#getParameter(String key, String defaultValue)
方法中,获取cluster
的配置。 这个方法最后从URL
的parameters
属性中获取对应的值。到这里,我们又有另外一个疑问。为什么从
parameters
中获取不到配置的cluster
的值?如果能获取到我们配置的值,那就可以按照我们的配置来创建对应的Cluster
了。 但是我们不是有配置吗?为什么会拿不到?dubbo 是如何填充URL parameters
的值的?2、dubbo 如何加载配置,并将配置放到 URL parameters 中?为什么 parameters 中没有我们配置的参数?
dubbo 的配置加载由
DubboBootstrap
负责。现在把断点打到DubboBootstrap#initialize()
上具体的配置加载,可以自行看下,这部分不是重点,你只要知道, dubbo 有把我们的配置加载出来即可。
加载完配置,现在就看下,dubbo 如何为我们生成 URL 的。
断点打到
ConfigValidationUtils#loadRegistries(AbstractInterfaceConfig interfaceConfig, boolean provider)
在方法里面,dubbo 会从
AbstractInterfaceConfig
(被加载的配置) 加载配置,以下是核心的代码。问题就出在这里:这个加载配置的方法,并没有将
AbstractInterfaceConfig
中的 cluster 放到 URL 中。因此,导致我们在创建对应的
Cluster
时,拿到的是默认的failover
。从我个人理解来看,这应该是 bug \~\~\~。当然可能不对,欢迎大佬指正
2.7.8 流程
2.7.8 的流程 整体和 2.7.7 一样。主要是获取
Cluster
的方法方法不大一样。2.7.7 生成 Cluster 主要逻辑
下图是 2.7.7
RegistryProtocol#refer(Class<T> type, URL url)
方法的代码Cluster
是一个动态加载的类。从 2.7.7 的流程中,可以知道,此时 URL 中的parameters
参数没有cluster
。因此,加载出来的Cluster
一定是默认的FailoverCluster
。在看下方法中, qs 局部变量,有我们配置的值。
2.7.8 生成 Cluster 主要逻辑
现在来看 2.7.8 如何解决这个 bug,其实挺简单的。下面贴上 2.7.8 的代码
多加一段代码,从 qs 中获取
cluster
的值,此时获取的Cluster
就是对的了!总结
太难了~ 刚学 dubbo 就遇到源码级别的 bug
~,差点劝退了~。