1、在springcloud中,使用的是ribbon来解决负载均很的问题,而常见的负载均衡策略包括有
1)轮询
2)随机
3)一致性哈希
4)哈希
5)加权
2、在ribbon中提供了ILoadBalance接口用来代表负责均衡的操作,它提供了增加服务器,选择服务器,标记服务器状态为down,获得可用服务器以及获得所有服务器的操作
public interface ILoadBalancer {
void addServers(List<Server> var1);
Server chooseServer(Object var1);
void markServerDown(Server var1);
/** @deprecated */
@Deprecated
List<Server> getServerList(boolean var1);
List<Server> getReachableServers();
List<Server> getAllServers();
}
3、ribbon中具体实现负载均衡的策略是通过IRule这个接口来实现的,接口实现结构图
4、ribbon默认是使用的是zoneAvoidanceRule规则,这里我们修改规则使用随机算法
默认ribbon规则的配置
@Bean
@ConditionalOnMissingBean
public IRule ribbonRule(IClientConfig config) {
if (this.propertiesFactory.isSet(IRule.class, this.name)) {
return (IRule)this.propertiesFactory.get(IRule.class, config, this.name);
} else {
ZoneAvoidanceRule rule = new ZoneAvoidanceRule();
rule.initWithNiwsConfig(config);
return rule;
}
}
// 来自 RibbonClientConfiguration
自定义为随机访问的策略 /**
* 该类为Ribbon的配置类
* 该类不能被@ComponentScan扫描到
* @author nicker
* @description
* @date 2018/5/16 18:25
* @
*/
@Configuration
public class RibbonConfiguration {
@Bean
public IRule ribbonRule() {
// 负载均衡规则,改为随机
return new RandomRule();
}
}
5、自定义指定ribbon客户端的配置
/**
* 使用RibbonClient,为特定name的Ribbon Client自定义配置
* 使用@RibbonClient的configuration属性,指定Ribbon的配置类
* @author nicker
* @description
* @date 2018/5/16 18:27
*/
@Configuration
@RibbonClient(name = "service-provider-user", configuration = RibbonConfiguration.class)
public class TestConfiguration {
}
6、controller层的api代码
/**
* @author nicker
* @description
* @date 2018/5/16 14:31
*/
@RestController
public class MovieController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id){
User user = restTemplate.getForObject("http://service-provider-user/" + id, User.class);
return user;
}
@GetMapping("/user-instance")
public List<ServiceInstance> showInfo() {
return discoveryClient.getInstances("service-provider-user");
}
@GetMapping("/log-user-instance")
public void logUserInstance() {
ServiceInstance serviceInstance = loadBalancerClient.choose("service-provider-user");
//打印当前选择的是哪个节点
System.out.println(serviceInstance.getServiceId()+serviceInstance.getHost()+serviceInstance.getPort());
}
}
7、在访问/log-user-instance这个接口的时候,使用自定义的策略对应的结果
8、通过application.yml中配置的方式,这里就不用使用前面的编程式配置了
格式如下<clientName>.ribbon.
NFLoadBalancerClassName: 配置ILoadBalancer的实现类
NFLoadBalancerRuleClassName: 配置IRule的实现类
NFLoadBalancerPingClassName: 配置IPing的实现类
NFWSServerListClassName: 配置ServerList的实现类
NIWSServerListFilterClassName: 配置ServerListFilter的实现类
本案例的测试,直接使用随机规则 service-provider-user:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
9、ribbon自带的几个负载均衡规则说明
策略名 | 策略声明 | 策略描述 | 实现说明 |
BestAvailableRule | public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule | 选择一个最小的并发请求的server | 逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server |
AvailabilityFilteringRule | public class AvailabilityFilteringRule extends PredicateBasedRule | 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值) | 使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态 |
WeightedResponseTimeRule | public class WeightedResponseTimeRule extends RoundRobinRule | 根据相应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。 | 一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成statas时,使用roubine策略选择server。 |
RetryRule | public class RetryRule extends AbstractLoadBalancerRule | 对选定的负载均衡策略机上重试机制。 | 在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server |
RoundRobinRule | public class RoundRobinRule extends AbstractLoadBalancerRule | roundRobin方式轮询选择server | 轮询index,选择index对应位置的server |
RandomRule | public class RandomRule extends AbstractLoadBalancerRule | 随机选择一个server | 在index上随机,选择index对应位置的server |
ZoneAvoidanceRule | public class ZoneAvoidanceRule extends PredicateBasedRule | 复合判断server所在区域的性能和server的可用性选择server | 使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。 |
版权声明:本文为qq_31489805原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。