SpringCloud-Ribbon负载均衡工具
官网手册:https://www.springcloud.cc/spring-cloud-dalston.html
Ribbon的介绍
Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项,如连接超时,重试等,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。
说白了,服务消费者在此就是客户端,Ribbon可以为我们的服务消费者提供一些负载均衡的算法来请求我们Eureka中的可用服务列表,当然,可用服务列表是由服务提供者注册所生成的。
Ribbon的实现
先来看看一个原始的消费者代码
application.yml
server:
port: 8080
ConfigBean
在我们服务的调用过程中,需要使用到了一个工具,叫做 RestTemplate,RestTemplate 是由 Spring 提供的一个 HTTP 请求工具,我们消费者用该工具请求服务提供者所提供的接口
@Configuration public class ConfigBean { //RestTemplate @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
UserController
@RestController public class UserController { @Autowired private RestTemplate restTemplate; //服务提供者的URL private static final String REST_URL_PREFIX="http://localhost:8081"; @RequestMapping("/consumer/getUser") public String getUser(){ return restTemplate.getForObject(REST_URL_PREFIX+"/get",String.class); } @RequestMapping("/consumer/getUsername") public User getUserByName(@RequestParam("username") String username){ return restTemplate.getForObject(REST_URL_PREFIX+"/getUsername?username="+username,User.class); } }
这就是消费者的一个原始形态,可这样做的消费者由上可看出,服务提供者的URL是写死了的,但是往往在我们的环境中服务提供者也不可能是单独一个的,所以我们需要结合上Eureka和Ribbon来对上方代码进行一个更改
Maven
导入Eureka和Ribbon的依赖
<!--Eureka-Client依赖,里面集成了Ribbon--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
application.yml
配置上Eureka-Client
server:
port: 8080
eureka:
client:
register-with-eureka: false #不向Eureka注册自己
service-url:
defaultZone: http://Eureka-Server1:7001/eureka/,http://Eureka-Server2:7002/eureka/ #Eureka集群只需要用逗号分隔即可
Controller
@RestController public class UserController { @Autowired private RestTemplate restTemplate; //这里需要配置成Eureka上的服务名,并且这样我们就可以无需去关心服务提供者的IP及端口 private static final String REST_URL_PREFIX="http://SPRINGCLOUD-PROVIDER-USER"; @RequestMapping("/consumer/getUser") public String getUser(){ return restTemplate.getForObject(REST_URL_PREFIX+"/get",String.class); } @RequestMapping("/consumer/getUsername") public User getUserByName(@RequestParam("username") String username){ return restTemplate.getForObject(REST_URL_PREFIX+"/getUsername?username="+username,User.class); } }
此时我们就可以通过服务提供者在Eureka上注册成功的服务名来进行请求,此外我们还需要配置上Ribbon来进行一个负载均衡设置
Config
@Configuration
public class ConfigBean {
//配置负载均衡实现RestTemplate
@Bean
@LoadBalanced //Ribbon
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
启动类
@SpringBootApplication @EnableEurekaClient //开启Eureka Client public class SpringcloudConsumerUser8080Application { public static void main(String[] args) { SpringApplication.run(SpringcloudConsumerUser8080Application.class, args); } }
为了更好的验证负载均衡的功能,我们可以创建一个相同接口的服务提供者
但是需要注意,服务提供者的名称需一致,这样在Eureka上注册的时候,才会被划分在一起
此时我们的消费者再发出请求时,就会根据Ribbon的默认算法(轮询)来访问我们Eureka上一个服务名称内的列表了
自定义Ribbon算法规则
Ribbon算法有哪些?
AvailabilityFilteringRule: 先过滤掉跳闸,访问故障的服务,再对剩下的服务进行轮询 RoundRobinRule:轮询调度,默认的 RandomRule:随机调度 WeightedResponseTimeRule:根据权重调度 RetryRule:会先轮询获取服务,如果获取失败,则会在一定的时间内进行重试
接下来我们来更改Ribbon的默认算法,我们需要重新创建一个包来定义
注意:自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是说,我们达不到特殊化定制的目的了,下方我们是单独对SPRINGCLOUD-PROVIDER-USER服务定制Ribbon算法。
MyRuleConfig
@Configuration public class MyRuleConfig { @Bean public IRule iRule(){ return new RandomRule(); } }
启动类
单独给Eureka上的SPRINGCLOUD-PROVIDER-USER服务名称定制Ribbon算法@SpringBootApplication @EnableEurekaClient @RibbonClient(name = "SPRINGCLOUD-PROVIDER-USER",configuration = MyRuleConfig.class) public class SpringcloudConsumerUser8080Application { public static void main(String[] args) { SpringApplication.run(SpringcloudConsumerUser8080Application.class, args); } }