负载均衡Ribbon
Ribbon是Netflx发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。
springboot加载配置
@Configuration
public class RibbonConfig {
@Primary @Bean public IRule getRule() { // 实现带有权重的负载均衡策略 return new DefaultGrayLoadBalancerRule(); }
}
Ribbon核心组件IRule
RoundRobinRule:轮询,出厂默认使用轮询;
RandomRule:随机;
RetryRule:先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用服务;
WeightedResponseTimeRule:对RandomRule的扩展,响应速度越快的实例选择权重越大,越容易被选择;
BestAvaliableRule:会先过滤由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量小的服务;
AvailabilityFilteringRule:先过滤掉故障实例,再选择并发较小的实例;
ZoneAvoidanceRule:默认规则,复合判断server所在区域的性能和server的可用性选择服务器。
实现choose方法
可以获取nacos,实现负载均衡
```java @Override public Server choose(Object key) { try { NamingService namingService = this.nacosDiscoveryProperties.namingServiceInstance(); // 获取到所有的目标实例 DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer(); String serverName = ""; if (key != null && !StrUtil.isEmpty((String) key)) { serverName = (String) key; } else { serverName = loadBalancer.getName(); } List<Instance> instances = namingService.selectInstances(serverName, true); if (CollectionUtils.isEmpty(instances)) { log.warn("no instance in service {}", serverName); return null; } List<Instance> instancesToChoose = instances(instances); if (CollectionUtils.isEmpty(instancesToChoose)) { log.warn("no instance in service {}", serverName); return null; } String clusterName = this.nacosDiscoveryProperties.getClusterName(); if (StringUtils.isNotBlank(clusterName)) { List<Instance> sameClusterInstances = instancesToChoose.stream() .filter(instance -> Objects.equals(clusterName, instance.getClusterName())) .collect(Collectors.toList()); if (!org.springframework.util.CollectionUtils.isEmpty(sameClusterInstances)) { instancesToChoose = sameClusterInstances; } else { log.warn( "A test-cluster,name = {}, clusterName = {}, instance = {}", serverName, clusterName, instancesToChoose); } } // 保留nacos默认负载均衡 Instance instance = ExtendBalancer.getHostByRandomWeight2(instancesToChoose); return new NacosServer(instance); } catch (Exception e) { log.warn("Nacos error", e); return null; } }
Autowired自动装载
@Autowired
protected NacosDiscoveryProperties nacosDiscoveryProperties;
instances实现
protected List<Instance> instances(List<Instance> instances) { List<Instance> target = new ArrayList<>(); List<Instance> defaults = new ArrayList<>(); List<Instance> result; String fromRegion = GrayContextHolder.getCurrentGrayContext().get("default"); // 匹配满足region的实例 for (Instance instance : instances) { Map<String, String> tarMetadata = instance.getMetadata(); // 目标实例 instancesResult .add(instance); } instancesResult = instancesTarget; return instancesResult; }
运行后,在nacos操作后台可以查看到主机内容。