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);
Ribbon内置的负载均衡策略
规则名称 | 特点 |
---|---|
AvailabilityFilteringRule | 过滤掉一直连接失败的被标记为circuit tripped的后端Server,并过滤掉那些高并发的后端Server或则使用一个AvailabilityPredicate来包含过滤Server的逻辑,其实就是检查status里面记录的各个Server的运行状态 |
BestAvailableRule | 找出并发请求最小的服务实例来使用。然而loadBalancerStats有可能为null,如果loadBalancerStats为null,则BestAvailableRule将采用它的父类即ClientConfigEnabledRoundRobinRule的服务选取策略(线性轮询) |
RandomRule | 随机选择一个Serve |
RetryRule | 这种负载均衡策略带有重试功能。首先RetryRule中又定义了一个subRule,它的实现类是RoundRobinRule,然后在RetryRule的choose(ILoadBalancer lb, Object key)方法中,每次还是采用RoundRobinRule中的choose规则来选择一个服务实例,如果选到的实例正常就返回,如果选择的服务实例为null或者已经失效,则在失效时间deadline之前不断的进行重试(重试时获取服务的策略还是RoundRobinRule中定义的策略),如果超过了deadline还是没取到则会返回一个null。 |
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 {
}
属性配置如下:
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);
}
}
}
理论
1,服务发现与注册的原理
2,cloud服务发现的通用流程
3,什么是负载均衡,意义是什么?
4,Ribbon是什么,跟cloud有什么关系
5,Ribbon里面常见的负载均衡的算法有哪些
6,Riboon里面两种配置方式的特点与区别
7,自定义负载均衡算法的流程
8,nacos的领域模型
代码
1,掌握RestTemplate的基本使用
2,掌握RestTemplate集成Ribbon
3,掌握Ribbon的配置
4,掌握自定义负载均衡的算法
5, 掌握nacos领域模型的配置
6,了解cloud通用服务发现的接口
7,了解Ribbon的属性位置
8,了解Riboon的配置类