Ribbon是什么
Ribbon是Netflix发布的云中间层服务开源项目,主要功能是提供客户端(消费者方)负载均衡算法。Ribbon客户端组件提供一系列完善的配置项,如,连接超时,重试等。简单的说,Ribbon是一个客户端负载均衡器,我们可以在配置文件中列出loadBalancer后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用Ribbon实现自定义的负载均衡算法。
RestTemplate在访问服务的时候加入负载均衡
@Bean@LoadBalanced //加上该注解就会集成负载均衡public RestTemplate rt() {return new RestTemplate();}
//负载均衡访问:
String value = rt.getForObject("http://注册到nacos的服务名/user/findUser", String.class);
- 负载均衡是什么?有什么意义?
- cloud里面谁来做负载均衡(LoadBlancedClient)
Ribbon内置的负载均衡策略
| 规则名称 | 特点 | | :—- | :—- | | AvailabilityFilteringRule | 过滤掉一直连接失败的被标记为circuit tripped的后端Server,并过滤掉那些高并发的后端Server或则使用一个AvailabilityPredicate来包含过滤Server的逻辑,其实就是检查status里面记录的各个Server的运行状态 | | BestAvailableRule | 选择一个最小的并发请求的Server,逐个考察Server,如果Server被tripped了,则跳过 | | RandomRule | 随机选择一个Server | | RetryRule | 对选定的负载均衡策略机上重试机制,在一个配置时间段内当选择Server不成功,则一直尝试使用subRule的方式选择一个可用的Server | | RoundRobinRule | 轮询选择,轮询index,选择index对应位置的Server | | WeightedResponseTimeRule | 根据响应时间加权,响应时间越长,权重越小,被选中的可能性越低 | | ZoneAvoidanceRule | 符合判断Server所Zone的性能和Server的可用性选择Server,在没有Zone的环境下,类似于轮询(RoundRobinRule) |
Ribbon的配置接口(了解)
| 接口 | 配置 | 默认值 |
|---|---|---|
| IClientConfig | 读取配置 | DefaultClientConfigImpl |
| IRule | 负载均衡规则,选择实例 | ZoneAvoidanceRule |
| IPing | 筛选掉ping不通的实例 | DummyPing |
| ServerList | 交给Ribbon的实例列表 | Ribbon:ConfigurationBasedServerList Spring Cloud Alibaba:NacosServerList |
| ServerListFilter | 过滤掉不符合条件的实例 | ZonePreferenceServerListFilter |
| ILoadBalancer | Ribbon的入口 | ZoneAwareLoadBalancer |
| ServerListUpdater | 更新交给Ribbon的List的策略 | PollingServerListUpdater |
Ribbon基础配置
Ribbon有两种配置方式,一是java代码配置,一种是属性配置。
代码配置如下:
@Configuration
public class RibbonConfig {
//添加负载均衡策略对象
@Bean
public IRule createIRule() {
return new WeightRule();
}
}
把上面的配置类用到主配置上面:
@Configuration
//全局配置
@RibbonClients(defaultConfiguration = RibbonConfig.class)
//局部配置
//@RibbonClient(value = "服务名",configuration = RibbonConfig.class)
public class BaseConfig {
}
属性配置如下:
<clientName>.ribbon:
NFLoadBalancerClassName: ILoadBalancer实现类
NFLoadBalancerRuleClassName: IRule实现类
NFLoadBalancerPingClassName: IPing实现类
NIWSServerListClassName: ServerList实现类
NIWSServerListFilterClassName: ServerListFilter实现类
自定义Ribbon的负载均衡规则
自定义类实现IRule接口或则继承AbstractLoadBalancerRule
public class WeightRule extends AbstractLoadBalancerRule {
//自身信息对象
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
//nacos服务管理对象
@Autowired
private NacosServiceManager nsm;
@Override
public Server choose(Object key) {
//获取需要访问的服务名
BaseLoadBalancer ilb = (BaseLoadBalancer)this.getLoadBalancer();
String name = ilb.getName();
//获取自身的clusterName
String clusterName = nacosDiscoveryProperties.getClusterName();
//获取nacos服务发现对象
NamingService ns = nsm.getNamingService(nacosDiscoveryProperties.getNacosProperties());
try {
//获取所有的需要访问的服务节点
List<Instance> insts = ns.getAllInstances(name);
//过滤出相同集群的节点
List<Instance> clusterInstances = insts.stream().filter(x -> {
if(StringUtils.isNotEmpty(clusterName) && StringUtils.isNotEmpty(x.getClusterName())) {
if(clusterName.equals(x.getClusterName())) return true;
}
return false;
}).collect(Collectors.toList());
insts = clusterInstances != null && clusterInstances.size() > 0 ? clusterInstances:insts;
//通过权重算法获取该服务的一个实例
Instance instance = MyBalancer.getHostByRandomWeight(insts);
return new NacosServer(instance);
} catch (NacosException e) {
e.printStackTrace();
return null;
}
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
//拉取权重调用算法
static class MyBalancer extends Balancer {
public static Instance getHostByRandomWeight(List<Instance> hosts) {
return Balancer.getHostByRandomWeight(hosts);
}
}
}
