一、本地负载均衡和Nginx负载均衡的区别
1、本地负载均衡
消费者服务从我们的注册中心获取到集群地址列表,缓存到JVM本地,本地采用负载均衡策略,实现RPC的远程调用。之所以叫本地感觉是相对的,消费者基于生产者就好比是客户端和服务端之间的关系,所以这也叫本地负载均衡吧。
2、Nginx负载均衡
客户端的所有请求都会交给Nginx代理,转发到相应的服务器上,这个是服务器端的负载均衡。
二、ribbon中的负载均衡规则
1、ribbon中IRule的实现类图解
2、各个类的作用
策略类型 | 策略说明 |
---|---|
RoundRobinRule | 轮循。相当于就是将访问次数和集群数(从注册中心获取到指定为服务名的集群地址列表的数量)进行取模计算出index,根据index取到相应的server |
RandomRule | 随机。在index上随机,选择index对应位置的server |
RetryRule | 选定的负载均衡策略机上重试机制。 |
BestAvailableRule | 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务 |
AvailabilityFilteringRule | 先过滤掉故障实例,再选择并发较小的实例 |
ZoneAvoidanceRule | 默认策略。复合判断server所在区域的性能和server的可用性选择server,如果微服务没设置zone,底层采用的还是轮循 |
WeightedResponseTimeRule | 响应速度越快的实例选择权重越大,越容易被选择 |
3、配合nacos实现自定义权重的负载均衡策略
相当于是每个注册的微服务都对应这么一个配置类。
成员变量中有这么一个:private static NamingService namingService;
,接口中有这么一个使用给定负载均衡算法的方法。
/**
* Select one healthy instance of service using predefined load balance strategy
*
* @param serviceName name of service
* @return qualified instance
* @throws NacosException
*/
Instance selectOneHealthyInstance(String serviceName) throws NacosException;
AbstractLoadBalancerRule已经帮我们实现了IRule接口中的一些方法,直接继承来得简单方便。
public class NacosWeightRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
//一般都是为空
}
@Override
public Server choose(Object o) {
BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
String name = loadBalancer.getName(); //获取到想要请求的微服务名称
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance(); //拿到服务发现的API
Instance instance = null;
try {
instance = namingService.selectOneHealthyInstance(name); //自带权重的负载均衡算法
} catch (NacosException e) {
e.printStackTrace();
return null;
}
return new NacosServer(instance);
}
}
将权重的负载均衡策略配置成全局。
@Configuration
public class RibbonConfiguration {
@Bean
public IRule nacosClusterRule() {
return new NacosClusterWeightRule();
}
}
启动类加上@RibbonClients(defaultConfiguration = RibbonConfiguration.class)
。
基于集群优先调用的权重负载均衡算法也同理,相当于再增加一步对集群名进行过滤并放入新的集合中。再判断一下新集合是否为空,为空就直接用上面的API,不为空也是类似上面的操作。
三、测试