同时使用@LoadBalanced @RefreshScope注解负载均衡失效分析

作者:毕小宝 时间:2023-12-07 10:59:24 

背景

最近引入了 Nacos Config 配置管理能力,说起来用法很简单,还是踩了三个坑。

  • Nacos Config 的 nacos 的帐号密码加密配置后,怎么解密而且在 NacosConfigBootstrapConfiguration 真正注入 Nacos Config 注入之前,而且不能触发 NacosDiscoveryPropertiesisNacosDiscoveryInfoChanged 变动事件。因为 NacosDiscoveryProperties 接受 NacosContextRefresher 事件时,还是从 yml 配置中获取属性,不会从 Environment 对象中加载。

  • @RefreshScope 要想生效,该注意什么?非 shared-config 的配置变动时,要想实时生效,必须在当前应用的 bootstrap.yml 中配置 spring.application.name 属性,注册该应用在配置中心需要监听的配置。

  • @RefreshScope + @LoadBalanced 同时使用导致 Ribbon 负载均衡失效问题。

问题一比较复杂,此处不做讨论,本文记录问题三的解决方法及个人思考。

问题

有个模块使用了 @LoadBalanced 负载均衡,通过配置控制超时时间。

引入 Nacos Config 配置后,按照常规用法,在对象上添加了 @RefreshScope 属性,希望配置变动时,能实时生效。

注入代码如下:

@Value("${rest.template.connect-timeout:10000}")
private Integer connectTimeout;
@Value("${rest.template.read-timeout:10000}")
private Integer readTimeout;
@Bean
@RefreshScope
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder builder){
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
     requestFactory.setConnectTimeout(connectTimeout); //连接超时设置
     requestFactory.setReadTimeout(readTimeout); //读写超时设置
     RestTemplate restTemplate = new RestTemplate(requestFactory);
     logger.info("初始化负载均衡的 RestTemplate 对象 {} {}", connectTimeout, readTimeout);
     return restTemplate;
 }

修改配置中心的配置后,可以监控到 RestTemplate 会在配置变化后重新初始化了,也打印了最新的配置。

同时使用@LoadBalanced @RefreshScope注解负载均衡失效分析

但真正使用这个类,调用某个服务时,出现了服务无法解析的异常:

同时使用@LoadBalanced @RefreshScope注解负载均衡失效分析

分析

首先,检查调用的目标服务是否注册成功,目标服务是正常启动的。

其次,对比其他同样引用了 @LoadBalancedRestTemplate 的模块,它调用是正常的。

最后,对比异常调用和正常调用的注入代码的区别,多了一个 @RefreshScope ,调整代码验证结果正常。引入 @RefreshScope 时,在配置变化后才会发生这个异常,首次运行时正常的。

延伸搜索发现,负载均衡 RestTemplate 也有类似的问题 @scope("prototype")+@loadbalanced注解时负载均衡失效问题。

启示录

@LoadBalanced@RefreshScope 同时使用,首次初始化时,RestTemplate 对象具有负载均衡的能力;当 Nacos 配置中的配置变动时,这个对象会重新创建,而且此时并没有使用 @LoadBalanced 的能力,导致负载均衡失效。

就是说,这两个注解同时使用时,在不同的时机,只会有一个注解生效:

  • 初始创建时,@LoadBalanced 生效,系统中的实例是负载均衡的 RestTemplate

  • 当 Nacos 配置变化,NacosContextRefresher 触发通知 @RefreshScope 注解的 @Bean 对象时,重新创建的实例就是普通的 RestTemplate 了。

引入任何一个第三方工具,面对的都是黑盒,各种资料用法看似简单,一用就坑不断啊!建议 Nacos Config 官方配置给出一个使用建议 @RefreshScope 不要用在 @LoadBalanced 注解上。

最后记录一个偶然的发现:

同时使用@LoadBalanced @RefreshScope注解负载均衡失效分析

选中几个图片文件后,右侧概览图是一个堆叠的图,才注意到!

来源:https://juejin.cn/post/7198099134363353125

标签:@LoadBalanced,@RefreshScope,注解失效,负载均衡
0
投稿

猜你喜欢

  • SpringBoot对Druid配置SQL监控功能失效问题及解决方法

    2023-06-10 21:31:24
  • C# Socket网络编程实例

    2023-03-18 05:09:28
  • Java经典用法总结(二)

    2023-11-24 20:39:10
  • Spring jackson原理及基本使用方法详解

    2021-10-03 08:28:18
  • Java并发编程之显示锁ReentrantLock和ReadWriteLock读写锁

    2023-06-04 04:54:22
  • Java Springboot 重要知识点整理汇总

    2022-03-17 01:06:57
  • Spring boot配置绑定和配置属性校验的方式详解

    2022-04-21 03:06:06
  • Elasticsearch percolate 查询示例详解

    2021-07-15 04:57:54
  • Javaweb动态开发最重要的Servlet详解

    2023-04-09 20:11:17
  • java 注解默认值操作

    2023-08-25 20:31:38
  • Spring Boot中@Conditional注解介绍

    2022-03-03 15:23:37
  • Android消息机制Handler的工作过程详解

    2023-07-31 13:49:03
  • java通过Idea远程一键部署springboot到Docker详解

    2022-03-26 09:31:27
  • RocketMQ存储文件的实现

    2023-03-16 15:11:27
  • Android仿支付宝微信支付密码界面弹窗封装dialog

    2021-10-24 13:13:31
  • Java十分钟精通类 封装 继承

    2023-11-25 10:55:58
  • MyBatis中resultType和parameterType和resultMap使用总结

    2023-04-01 05:43:42
  • spring mvc高级技术实例详解

    2022-10-11 12:50:15
  • Android 实现视频字幕Subtitle和横竖屏切换示例

    2023-02-06 07:29:37
  • C#操作RabbitMQ的完整实例

    2022-05-05 19:41:05
  • asp之家 软件编程 m.aspxhome.com