rabbon为其所有的组件都定义了接口
注意在使用ribbon根据nacos的权重自定义负载均衡的时候,要匹配nacos和springboot和springCloud的版本
- IclientConfig 读取配置 DefaultClientConfigImpl
- IRule 负载均衡规则,选择实例 ZoneAvoidanceRule
- IPing 筛选掉ping不通的实例 DumyPing(该类什么不干,认为每个实例都可用,都能ping通)
- ServerList 交给Ribbon的实例列表 Ribbon:ConfigurationBasedServerList Spring
Cloud Alibaba:NacosServerList - ServerListFilter 过滤掉不符合条件的实例 ZonePreferenceServerListFilter
- ILoadBalancer Ribbon的入口 ZoneAwareLoadBalancer
- ServerListUpdater 更新交给Ribbon的List的策略 PollingServerListUpdater
Iping
Iping
中默认的DummyPing
什么都不干,认为每个实例都可用,都能ping通,看名字就知道了Dummy
(假的)
可以自己替换成其他真正有用的实现类
windows下查看实现类的快捷键ctrl+alt+b
Ribbon的负载均衡规则
- AvailabilityFilteringRule 过滤掉一直连接失败的被标记为circuit
tripped(电路跳闸)的后端Service,并过滤掉那些高并发的后端Server或者使用一个 - AvailabilityPredicate来包含过滤Server的逻辑,其实就是检查status的记录的各个Server的运行状态
- BestAvailableRule 选择一个最小的并发请求的Server,逐个考察Server,如果Server被tripped了,则跳过
- RandomRule 随机选择一个Server
- ResponseTimeWeightedRule 已废弃,作用同WeightedResponseTimeRule
- RetryRule 对选定的负责均衡策略机上充值机制,在一个配置时间段内当选择Server不成功,则一直尝试使用subRule的方式选择一个可用的Server
- RoundRobinRule 轮询选择,轮询index,选择index对应位置Server
- WeightedResponseTimeRule 根据相应时间加权,相应时间越长,权重越小,被选中的可能性越低
- ZoneAvoidanceRule (默认是这个)负责判断Server所Zone的性能和
- Server的可用性选择Server,在没有Zone的环境下,类似于轮询(RoundRobinRule)
常用的ribbon负载均衡规则
方式一:java代码修改
比如下面,在调用testHashMap
服务的时候改成随机的模式,用代码实现的时候,如果是单独指定一个服务的负载均衡模式的要注意,要单独列一个包,不能让启动类扫描大,这里有一个父子上下文的问题.
不过这里也有一个取巧的方式,就是故意让spring扫描到,成为全局配置.调用所有服务的时候都采用这个负载均衡设置
java代码之全局配置
和针对某个服务的配置,全局配置只是修改了参数,很方便
yml属性配置负载均衡规则
可以配置的属性
NFLoadBalancerClassName: #ILoadBalancer该接口实现类
NFLoadBalancerRuleClassName: #IRule该接口实现类
NFLoadBalancerPingClassName: #Iping该接口实现类
NIWSServerListClassName: #ServerList该接口实现类
NIWSServerListFilterClassName: #ServiceListFilter该接口实现类
testHashMap:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
ribbon默认是懒加载的,即第一次调用的时候才加载,可以修改这个策略
ribbon的懒加载会造成第一次请求比较慢,因为需要在第一次调用的时候加载.
这个只需要开启饥饿加载
就可以了
在application.yml
中添加
ribbon:
eager-load:
enabled: true
clients: testHashMap #多个服务可以使用逗号分隔,不在这个名单里的服务被调用的时候依旧会采用懒加载
不过实测第一次调用依旧比第一次调用加载后要慢,感觉会在第一次调用之后加载到内存.
ribbon根据nacos权重访问
因为ribbon原生是不支持nacos的权重的,所以需要改造
自定义权重类
package com.fchen.usercenter.config;
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.Server;
import org.springframework.beans.factory.annotation.Autowired;
public class NacosWeightedRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties discoveryProperties;
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
//加载配置,默认留空
}
@Override
public Server choose(Object key) {
DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer();
String name = loadBalancer.getName();
try {
Instance instance = discoveryProperties.namingServiceInstance()
.selectOneHealthyInstance(name);
/*
* instance转server的逻辑参考自:
* org.springframework.cloud.alibaba.nacos.ribbon.NacosServerList.instancesToServerList
*/
return new NacosServer(instance);
} catch (NacosException e) {
return null;
}
}
}
ribbon这里我就全局设置了
自定义IRule实现类为自己的权重类