负载均衡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操作后台可以查看到主机内容。