设为首页 - 加入收藏  
您的当前位置:首页 >人工智能 >Dubbo 配置 Loadbalance 不生效?撸一把源码 正文

Dubbo 配置 Loadbalance 不生效?撸一把源码

来源:亿华互联编辑:人工智能时间:2025-11-05 15:50:06

文末本文转载自微信公众号「捉虫大师」,不生把源作者捉虫大师 。效撸转载本文请联系捉虫大师公众号。不生把源

背景

很久之前我给业务方写了一个 dubbo loadbalance 的效撸扩展(为了叙述方便,这个 loadbalance 扩展就叫它 XLB 吧),不生把源这两天业务方反馈说 XLB 不生效了

我心想,效撸不可能啊,不生把源都用了大半年了~

排查

于是效撸我登上不生效的 consumer 机器进行排查,还好我留了一手,不生把源当 XLB 加载时,效撸会打印一行日志

看了下这个服务,不生把源并没有打印日志,效撸说明 XLB 并没有加载成功

于是不生把源,我就去问对应的效撸开发,有按照我的不生把源文档配置 loadbalance 吗?答复:完全按照文档配置

这下我就有点不相信了,但转念一想,配置 loadbalance 如此简单,不应该出错啊,我的文档和他的应用都在 xml 文件中配置了 consumer 的 loadbalance

<dubbo:consumer loadbalance="xlb"/> 

两组配置相同,但顺序不同,测试结果为 case 1 可以加载到 XLB,case 2 不行

于是猜测,dubbo consumer 配置以后加载的为准

撸源码

显然猜测不符合我的IT技术网风格,下面开撸源码,不感兴趣可以划过,最下面有总结

首先搞清楚,何时会加载 loadbalance,在 AbstractClusterInvoker 的 invoke 方法中,加载了 loadbalance

@Override public Result invoke(final Invocation invocation) throws RpcException {     ...     List<Invoker<T>> invokers = list(invocation);     LoadBalance loadbalance = initLoadBalance(invokers, invocation);     RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);     return doInvoke(invocation, invokers, loadbalance); } 

加载代码如下

protected LoadBalance initLoadBalance(List<Invoker<T>> invokers, Invocation invocation) {     if (CollectionUtils.isNotEmpty(invokers)) {         return ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl()                 .getMethodParameter(RpcUtils.getMethodName(invocation), LOADBALANCE_KEY, DEFAULT_LOADBALANCE));     } else {         return ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(DEFAULT_LOADBALANCE);     } } 

带缓存的加载扩展

public T getExtension(String name) {     if (StringUtils.isEmpty(name)) {         throw new IllegalArgumentException("Extension name == null");     }     if ("true".equals(name)) {         return getDefaultExtension();     }     final Holder<Object> holder = getOrCreateHolder(name);     Object instance = holder.get();     if (instance == null) {         synchronized (holder) {             instance = holder.get();             if (instance == null) {                 instance = createExtension(name);                 holder.set(instance);             }         }     }     return (T) instance; } 

可以看出

loadbalance 是发起 dubbo 调用时,且当 invokers 非空时(即 providers 非空)会被初始化,后续都从缓存中取 loadbalance 是根据第一个 invoker 的 loadbalance 参数决定使用哪个 loadbalance 的

于是问题转移到 invoker 的 loadbalance 从哪来?provider 不会配置 loadbalance,所以这个参数一定是从 consumer 的配置上得到的

顺藤摸瓜,在 RegistryDirectory 的 toInvokers 方法中调用了 mergeUrl,它是在注册中心通知时被调用,也就是从注册中心上拿到 provider url 时,还得 merge 一下才能用,merge 了些什么内容?

private URL mergeUrl(URL providerUrl) {     // 1. merge consumer 参数     providerUrl = ClusterUtils.mergeUrl(providerUrl, queryMap);      // 2. merge configurator 参数     providerUrl = overrideWithConfigurator(providerUrl);     ...     return providerUrl; } 

1中 merge 了queryMap 里的参数,这个queryMap 其实就是 consumer 的参数,企商汇它来自配置的 reference

再看 reference 配置,当 ReferenceConfig 初始化时

public synchronized void init() {     ...     checkAndUpdateSubConfigs();     ...     AbstractConfig.appendParameters(map, consumer);     ... } // 2 public void checkAndUpdateSubConfigs() {     ...     checkDefault();     ... } // 3 public void checkDefault() throws IllegalStateException {     if (consumer == null) {         consumer = ApplicationModel.getConfigManager()                 .getDefaultConsumer()                 .orElse(new ConsumerConfig());     } } // 4 public Optional<ConsumerConfig> getDefaultConsumer() {     List<ConsumerConfig> consumerConfigs = getDefaultConfigs(getConfigsMap(getTagName(ConsumerConfig.class)));     if (CollectionUtils.isNotEmpty(consumerConfigs)) {         return Optional.of(consumerConfigs.get(0));     }     return Optional.empty(); } 

上面调用链从 1 到 4,4 中获取了第1个 consumer,这就是我们要找的根源

总结

每配置一个 consumer ,无论是从 xml 文件,或是 spring-boot 配置,或是 api 直接创建,都会生成一个 consumerConfig 对象

当消费接口,即配置 reference 时,会将 consumer 的参数 merge 过来,如果存在多个 consumer,会挑第一个,当然我们并不知道谁先加载

当 reference 存在 consumer 的配置时,注册中心通知的 provider urls 会和 reference 的参数进行合并,合并后生成可调用的 invoker

对于 loadbalance 来说,调用时,如果 invokers 非空,则会尝试通过第一个 invoker 的 loadbalance 参数加载负载均衡算法,第一次调用进行加载,后续调用则使用缓存

上一篇:充电器限流原理与应用(揭秘充电器如何实现电流限制,保护设备安全)
下一篇:华硕F81se系列电脑的用户在安装Ubuntu12.04系统是出现了错误,导致Ubuntu12.04安装失败,那么是什么原因导致系统安装失败呢?想要在华硕F81se上使用Ubuntu12.04系统怎么办?下面小编就给大家介绍下解决方法。问题:从ubuntu官网上下载了12.04的安装包,下了个usb installer,把系统烧到u盘以后,在u盘里run了下,总是出现下面的错误:Cannot allocate resource for EISA slot 1Cannot allocate resource for EISA slot 2Cannot allocate resource for EISA slot 3Cannot allocate resource for EISA slot 4Cannot allocate resource for EISA slot 5Cannot allocate resource for EISA slot 6Cannot allocate resource for EISA slot 7Cannot allocate resource for EISA slot 8解决方法:华硕电脑开机的时候,按F2进入bios设置,选择security选项,会看到如下图所示:按键盘上的上下键,把光标移动到I/O Interface Security 选项,敲回车,进入下图:默认情况下,这里面的所有的选项都是UNLOCKED 将最后一个选项New Card Interface 设置为LOCKED 这样就可以进入系统了,有人提到要将Wireless NetWork Interface 也设置为LOCED 这样有利于安装,要注意:ODD Interface 和USB Interface 千万不要设置为LOCKED 这样就关闭了USB 和光驱的功能。装完系统以后要把New Card Interface 设置为LOCKED,否则ubuntu 12.04将启动不了,其他的都要设置为UBLOCKED,到这里,基本上系统装的就没问题了。上面就是Ubuntu 12.04在华硕F81se电脑上安装失败的解决方法介绍了,只要你安装本文的步骤实施,你就能轻松使用上Ubuntu 12.04系统了。
最新文章

0.2503s , 11757.1015625 kb

Copyright © 2025 Powered by Dubbo 配置 Loadbalance 不生效?撸一把源码,亿华互联  滇ICP备2023000592号-16

sitemap

Top