eureka 集群通过 ribbon + resttemplate 实现负载负载均衡时,可以根据服务名称找到时机的 ip:port 地址,但找到地址后没有将服务名称进行替换,实际请求为 服务名称 + ip:port + port 这是因为什么?
并且可以实现负载均衡,多次调用采用了轮询调用。
版本信息:spring cloud 2021.0.6 + spring boot 2.7.6
这是因为版本冲突导致的吗?
@SpringBootApplication
@EnableEurekaClient
public class CustomerOrder80Application {
public static void main(String[] args){
SpringApplication.run(CustomerOrder80Application.class, args);
}
@Bean
@LoadBalanced // 开启负载均衡
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
根据你提供的代码来看,应该是 RestTemplate
的默认行为导致了这个问题。在默认情况下,如果你使用了 RestTemplate
进行服务调用,而服务名称没有被显式地替换,那么 RestTemplate
会将服务名称和实际的服务地址以及端口都拼接在一起形成最终的请求地址,从而导致服务名称被重复拼接的问题。
为了解决这个问题,你可以通过在创建 RestTemplate
实例时使用 LoadBalancerInterceptor
来实现服务名的替换。具体来说,你可以为 RestTemplate
注入 LoadBalancerInterceptor
,并为其添加 @LoadBalanced
注解,从而开启负载均衡。
示例代码如下:
@SpringBootApplication
@EnableEurekaClient
public class CustomerOrder80Application {
public static void main(String[] args){
SpringApplication.run(CustomerOrder80Application.class, args);
}
@Bean
@LoadBalanced // 开启负载均衡
public RestTemplate restTemplate(LoadBalancerInterceptor loadBalancerInterceptor) {
RestTemplate restTemplate = new RestTemplate();
// 添加 LoadBalancerInterceptor
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(loadBalancerInterceptor);
restTemplate.setInterceptors(interceptors);
return restTemplate;
}
}
在这个示例代码中,我们通过为 RestTemplate
注入 LoadBalancerInterceptor
来实现服务名的替换,并使用 @LoadBalanced
注解开启负载均衡。同时,在 RestTemplate
实例创建时,我们将 LoadBalancerInterceptor
添加到了 RestTemplate
的拦截器中。
另外,关于版本冲突的问题,确保你使用的 Spring Cloud 版本与 Spring Boot 版本兼容即可。如果你有其他版本的依赖项,也需要确保它们与 Spring Cloud 和 Spring Boot 版本兼容。你可以参考 Spring Cloud 的官方文档中关于版本兼容的说明来解决该问题。