RestTemplate+Ribbon实现客户端负载均衡的一个奇葩问题

搭建环境说明:

zookeeper #作为服务的注册中心

zero #服务消费者,一个实例

one #服务的提供者,创建了二个实例。

在zookeeper中注册成功,如下图所示:

RestTemplate+Ribbon实现客户端负载均衡的一个奇葩问题

zookeeper

在zero服务中我定义了一个RestTemplate:

<code>/** 
* @LoadBalanced注解,增加Ribbon功能,实现客户端负载均衡 
* @param builder * 
  @return 
  */
@Bean
@LoadBalanced
 public RestTemplate restTemplate(RestTemplateBuilder builder) {
   return  builder.build();
}/<code>

在zero服务中定义了一个访问one服务中的方法:

<code>@Autowired
private RestTemplate restTemplate;
@GetMapping("/getOne")
public void getOne(){
    //url会在zookeeper注册中心上通过name进行查找,restTemplate通过name来找服务,是依赖ribbon,所以RestTemplate初始化要加上@LoadBalanced    
  String url="http://one/commonOne/getOne";    
  String result=restTemplate.getForObject(url,String.class);   
  log.info(result);
}/<code>

在one服务中我定义了如下接口:

RestTemplate+Ribbon实现客户端负载均衡的一个奇葩问题

现象说明:

我在浏览器中,访问zero的这个服务接口连接:http://localhost:9998/zookeeperServices/getOne

这个接口的功能就是去one服务的getOne接口,因为one服务在zookeeper中定义了两个实例,所以会根据负载均衡策略,随机访问到,而打印出不同的端口号。但是在调用过程中,一直报错,提示可用的服务列表为空。

根本原因:

在Ribbon拿到one的实例列表后,本例子是2个,会调用ping方法去ping目标主机,ping的url是 http://ip:端口/health,这是spring boot给我们默认暴露的health端点,由于我在one服务的配置文件中定义了如下的配置management.endpoints.web.base-path=/actuator,就是给暴露的端点增加了base-path,导致在ping的时候接口返回失败,导致认为服务器不可用。


分享到:


相關文章: