Ribbon是Netflx发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。
@Configuration
public class RibbonConfig {
@Primary
@Bean
public IRule getRule() {
// 实现带有权重的负载均衡策略
return new DefaultGrayLoadBalancerRule();
}
}
RoundRobinRule:轮询,出厂默认使用轮询;
RandomRule:随机;
RetryRule:先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用服务;
WeightedResponseTimeRule:对RandomRule的扩展,响应速度越快的实例选择权重越大,越容易被选择;
BestAvaliableRule:会先过滤由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量小的服务;
AvailabilityFilteringRule:先过滤掉故障实例,再选择并发较小的实例;
ZoneAvoidanceRule:默认规则,复合判断server所在区域的性能和server的可用性选择服务器。
可以获取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
protected NacosDiscoveryProperties nacosDiscoveryProperties;
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操作后台可以查看到主机内容。