出现问题。
之前用ribbon做负载 均衡,切换ribbon的负载均衡算法,切换成 随机负载均衡算法,始终切换不了,
通过debug,发现在调用choose方法后,总是调到BlockingLoadBalancerClient实现类中,而不是调到RibbonLoadBalancerClient实现类。所以切换算法无效果。而且没有RibbonLoadBalancerClient实现类,和IRule类,即使添加了依赖包也不行。
解决办法:
是由于Spring cloud 版本的问题。用的boot版本是2.4.3,而spring-cloud版本是2020.0.1,settings.xml中配置的是aliyun的地址,可能是版本太新,导致一些jar包没有下载成功。
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>2020.0.1</spring-cloud.version>
</properties>
所以切换了boot版本,切换版本后发现报错了ClassNotFoundException: org.springframework.boot.Bootstrapper
查证后发现,springboot版本和spring cloud版本要严格匹配。
登录官网:https://spring.io/projects/spring-cloud#samples。参考官网信息选择版本。
在配置类中增加IRule的Bean。
package com.example.consumer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
public IRule TransRule(){
//轮询
// return new RoundRobinRule();
//随机
return new RandomRule();
}
}
在balancerClient.choose()的时候就变成随机
/**
* 负载均衡,在choose中自己找一个,同时过滤掉down的服务
*/
@RequestMapping("/f")
public String getF() {
RestTemplate restTemplate = new RestTemplate();
ServiceInstance provider = balancerClient.choose("provider");
String url = "http://" + provider.getHost() + ":" + provider.getPort() + "/hello";
System.out.println(url);
String forObject = restTemplate.getForObject(url, String.class);
System.out.println(forObject);
return "f";
}