Spring 负载均衡器、RestTemplate 和微服务问题

Posted

技术标签:

【中文标题】Spring 负载均衡器、RestTemplate 和微服务问题【英文标题】:Spring Load Balancer, RestTemplate, and Microservices issue 【发布时间】:2022-01-24 00:20:38 【问题描述】:

按照这个post,我配置了

(1) 一个 Eureka 服务器,

(2) 作为 (1) 的客户的收费服务,

(3) 从 (2) 读取数据的收费率仪表板。

在我使用@LoadBalanced 进行一些更改之前一切顺利(也许这不完全是由于负载平衡器,但我将在下面发布相关代码块)

(2)中的bootstrap.properties中,公共端点名称为

spring.application.name = demo-tollrate-service

在(3)中的DashboardController.java中,可以看到HTTP地址改成了上面的应用名

// import some libraries

@Controller
public class DashboardController 
    
    @Autowired
    private RestTemplate restTemplate;
    
    @LoadBalanced
    @Bean
        public RestTemplate restTemplate(RestTemplateBuilder builder) 
        return builder.build();
    
    
    @RequestMapping("/dashboard")
    public String GetTollRate(@RequestParam int stationId, Model m) 
        
        TollRate tr = restTemplate.getForObject("http://demo-tollrate-service/tollrate/" + stationId, TollRate.class);
        
        m.addAttribute("rate", tr.getCurrentRate());
        
        return "dashboard";
    
    

这个post中的pom.xml大致相同

运行此应用时,出现以下错误。

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

┌──->──┐
|  dashboardController (field private org.springframework.web.client.RestTemplate com.example.demo.DashboardController.restTemplate)
└──<-──┘


Action:

Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

有人可以帮我吗?谢谢。

【问题讨论】:

你试过用-debug运行吗? 它给出了同样的错误信息 【参考方案1】:

它有一个循环依赖,DashboardController依赖于RestTemplate,但是RestTemplate是在DashboardController内部定义的。

Java 版本没有任何区别,但可能是 Spring 版本。新的 Spring 版本默认不允许循环引用。您可以更改在 application.properties 文件中添加属性,在这里您可以找到更多详细信息:

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.6-Release-Notes#circular-references-prohibited-by-default

但我建议重构,没有充分的理由在控制器内部定义 RestTemplate,最好在 @Configuration 类中进行。

【讨论】:

【参考方案2】:

Spring 101:您不能在控制器类中定义 bean。将 RestRemplate 定义移动到 @Configuration 类或您的应用程序主类。

【讨论】:

感谢回复,不过这其实是根据导师的代码,对导师有效(他用Java 8,我用Java 11,会不会有区别?)

以上是关于Spring 负载均衡器、RestTemplate 和微服务问题的主要内容,如果未能解决你的问题,请参考以下文章

Spring RestTemplate作为负载平衡器客户端

Spring RestTemplate作为负载平衡器客户端

Spring Cloud Commons教程Spring RestTemplate作为负载平衡器客户端

Spring Cloud Alibaba - 06 RestTemplate 实现自定义负载均衡算法

RestTemplate 负载均衡原理

Spring Cloud客户端负载均衡 - Ribbon