1.Ribbon介绍
在分布式架构中,服务器端负载均衡通常是由Nginx实现分发请求的,而客户端同一个实例部署在多个应用上时,也需要实现负载均衡,在SpringCloud中提供了Ribbon实现负载均衡。
Ribbon是Netflix发布的开源项目,其主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon的客户端组件提供了一系列完善的配置项,例如连接超时重试等。
在Eureka的自动配置依赖模块Spring-cloud-starter-netfilx-eureka-client中已经集成了ribbon的依赖。
在Eureka和Ribbon二者同时使用时,Ribbon会利用从Eureka读取到的服务信息列表,在调用服务实例时,以合理的方式进行负载均衡。
Ribbon有一下一些 实现负载均衡的算法:
- RoundRobbinRule 轮询
- RandomRule 随机
- AvailabilityFilteringRule 会先过滤掉由于多次访问故障而处于短路器跳闸状态的服务,还有并发的连接数量超过阈值的服务,然后对剩余的服务列表按照轮询的策略进行访问。
- WeightedResponseTimeRule 根据平均响应时间计算所有服务的权重,响应时间越快服务权重越大被选中的概率越高,刚启动时如果统计信息不足,则使用RoundRibbonRule策略,等统计信息足够,会切换到WeightedResponseTimeRule.
- RetryRule 先按照RoundRobbinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务。
- BestAvaliableRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务。
- ZoneAvoidanceRule 默认规则,复合判断server所在区域的性能和server的可用性选择服务器。
2.Ribbon的使用
在Eureka中使用Ribbon,需要在实例化RestTemplate的方法上添加@LoadBalanced注解,并在调用服务时将服务ip和端口修改为服务名称即可。
即上一篇博客修改。在microservice-eureka-test工程中。添加注解。
@Component
public class RestTemplateConfigure {
/**
* 配置RestTemplate模板对象
* @return
*/
@Bean
@LoadBalanced //默认轮询负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
在消费者服务中,使用服务提供者的服务实例名称来执行已注册服务列表中的实例的方法。
@GetMapping("/hello")
public String hello(){
return restTemplate.getForObject("http://microservice-eureka-client/hello",String.class);
}
从上述代码中可以看出,getForObject()方法的URL使用已经不是"主机地址"+"端口"的形式,而使用注册中心的服务提供者的实例名称。
3.使用java代码自定义Ribbon配置
很多场景下,可能需要自定义Ribbon的配置,例如修改Ribbon的负载均衡规则等。SpringCloud Camden允许使用Java代码或属性自定义Ribbon的配置,两种方式是等价的。在SpringCloud中,Ribbon默认的配置类是RibbonClientConfiguration.也可使用一个POJO自定义Ribbon配置(自定义配置会覆盖默认配置)。这种配置是细粒度的,不同的Ribbon客户端可以使用不同的配置。
1.采用属性来修改实例名为microservice-eureka-client的Ribbon客户端的负载均衡规则。在项目中,将microservice-eureka-test的application.yml添加以下内容即可。
microservice-eureka-client:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
这样就可以将负载均衡规则修改为随机。
2.自定义负载均衡规则类
(1)创建MyRandomRule类 需要实现AbstractLoadBalancerRule,实现父类的choose和initWithNiwsConfig两个方法。并且自定义choose重载方法,自定义负载均衡算法规则。并在继承父类的choose方法中调用自定义重载的choose方法。
package com.mhc.configure;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.Random;
public class MyRandomRule extends AbstractLoadBalancerRule {
Random rand=new Random();
public Server choose(ILoadBalancer lb,Object key) {
if(lb==null){
return null;
}
Server server=null;
while(server==null){
if(Thread.interrupted()){
return null;
}
List<Server> upList=lb.getReachableServers();
List<Server> allList=lb.getAllServers();
int serverCount=allList.size();
if(serverCount==0){
return null;
}
int index=rand.nextInt(serverCount);
server=upList.get(index);
if(server==null) {
Thread.yield();
continue;
}
if(server.isAlive()){
return (server);
}
server=null;
Thread.yield();
}
return server;
}
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
@Override
public Server choose(Object o) {
return choose(getLoadBalancer(),o);
}
}
(2)创建RibbonConfigRule类,添加@Configure注解,实现IRule方法,并对此方法添加@Bean注解,并调用自定义的负载均衡规则类。
package com.mhc.configure;
import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RibbonConfigRule {
/**
* 自定义Ribbon负载均衡规则
*/
@Bean
public IRule myRule(){
return new MyRandomRule();
}
}
(3)在启动类添加@RibbonClient注解
@RibbonClient(name="microservice-eureka-client",configuration = RibbonConfigRule.class)
注:自定义的负载均衡配置类不能和主启动类在同一个包下。主启动类中的@SpringbootApplication注解包含@ComponentScan。自定义某一个Ribbon的客户端配置,必须防止@configuration注解的类所在的包与@ComponentScan扫描的包重叠,或应该显式的指定@ComponentScan不扫描这个配置类。
4.脱离eureka使用Ribbon
在前文的实例中,是将Ribbon与Eureka配合使用的,但现实不完全具备这样的条件,例如一些遗留的微服务,它们可能没有注册到eureka server中,甚至根本不是用springCloud开发的。因此Ribbon也支持脱离eureka使用。
1.在microservice-erueka-test工程中,在pom.xml文件中去掉eureka依赖,只使用Ribbon的依赖spring-cloud-starter-ribbon。
2.去掉启动类上的@EnableEurekaClient注解
3.修改application.yml为:
server:
port: 8084
spring:
application:
name: microservice-eureka-test
microservice-eureka-client:
ribbon:
listOfServers: localhost:8082,localhost:8083
4.启动服务。