Spring Boot从2.2.5升级到2.4.6后RestTemplate调用出现连接超时错误
问题产生原因
- 服务名解析能力缺失(高概率)
Spring Boot 2.4.x 对应配套的Spring Cloud 2020.0.x版本默认移除了原有的Ribbon负载均衡组件,改用Spring Cloud LoadBalancer作为官方默认负载均衡实现。如果升级Spring Boot版本时没有同步引入spring-cloud-starter-loadbalancer依赖,加了@LoadBalanced注解的RestTemplate就无法解析email-service这类注册中心的服务名,导致请求地址无效触发连接超时。 - 默认超时规则变更
Spring Boot 2.2.5.RELEASE版本中RestTemplate默认的连接超时、读取超时均为无限期,2.4.x版本调整了默认阈值,超时时间大幅缩短,如果邮件服务响应较慢就会直接触发超时报错。 - 代码不规范的副作用被放大
你提供的代码中每次调用邮件服务时都会执行restTemplate.setErrorHandler(new ExceptionHandler()),而RestTemplate是单例Bean,多线程并发调用时反复修改单例属性会导致内部状态混乱。2.4.x版本对RestTemplate的状态校验更严格,这类不规范写法更容易触发连接异常。
解决方案
1. 修复服务名解析能力
如果你的项目使用Spring Cloud服务发现能力,直接在依赖中添加Spring Cloud LoadBalancer组件即可:
Maven依赖配置:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency>
同时确认RestTemplate的Bean定义上仍保留@LoadBalanced注解。
2. 主动配置超时参数
可以通过Bean定义或者配置文件两种方式设置合理的超时时间:
方式一:Bean初始化时配置
@Bean public RestTemplate restTemplate() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); // 连接超时设为10秒,可根据业务场景调整 factory.setConnectTimeout(10000); // 读取超时设为30秒,可根据业务场景调整 factory.setReadTimeout(30000); RestTemplate restTemplate = new RestTemplate(factory); // 初始化时统一设置错误处理器,避免运行期修改 restTemplate.setErrorHandler(new ExceptionHandler()); return restTemplate; }
方式二:配置文件设置
spring: rest: template: connect-timeout: 10000 read-timeout: 30000
3. 修正代码不规范问题
删除emailServiceCall方法中的restTemplate.setErrorHandler(new ExceptionHandler())行,统一在Bean初始化时设置错误处理器,避免并发修改单例属性。
内容的提问来源于stack exchange,提问作者Prashant Raghav
相关产品推荐
相关产品推荐

