Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。Ribbon实现客户端的负载均衡,负载均衡器提供很多对http和tcp的行为控制。Spring cloud Feign已经集成Ribbon,所以注解@FeignClient的类,默认实现了ribbon的功能。它几乎存在于每一个Spring Cloud构建的微服务和基础设施中。在SpringCloud Alibabba组件中,当我们引入Nacos依赖的时候,也默认帮我们引入了Ribben的依赖。
**
**
使用ribben默认配置只需要定义一个RestTemplate的Bean并在方法上加上**@LoadBalanced** 的注解就可以使用了,默认负载均衡机制为轮训
@Bean
@LoadBalanced //ribbon的负载均衡注解
public RestTemplate restTemplate(){
return new RestTemplate();
}
**
**
1, RoundRobinRule
Rabon默认采用轮询策略。如果在一轮轮询后找不到提供者,它最多可以轮询10轮
如果没有找到,则返回NULL。
例如,目前有三个提供者A、B和C,逐个对它们进行一次轮询。A、B和C不访问(一轮)。A、B、C三次访问(两轮)十次,如果它还不能访问,则返回NULL。
2, RandomRule
随机策略,从所有可用的提供者中选择。
3, RetryRule
重试策略:首先根据RoundRobin Rule策略获取提供者(策略制定者),直接返回。如果检索失败,请在指定的时间限制内重试,
缺省情况下,时间限制为500毫秒。[RoundRobin Rule轮询策略。]默认为10发。我会给你500毫秒给RetryRule。您可以重试,直到您找到它。]
4, BestAvailableRule
最可行的策略。选择并发性最高的提供者,即连接消费者数量最低的提供者。
5, AvailabilityFilteringRule
可以实现滤波算法。算法规则为:过滤掉处于融合状态和超过连接限制的提供者,对剩余的提供者采用轮询策略。
6, ZoneAvoidanceRule
区回避策略。根据提供程序所在的区域和提供程序的可用性选择提供程序。
7, WeightedResponseTimeRule
权重响应时间策略。每个提供者的权重是根据其平均响应时间计算的。响应时间越快,选择权重的可能性就越大。
在启动初期,采用轮询策略。之后,您将根据重量进行选择。
1.配置文件yaml中进行配置
#给某一个服务配置负载均衡策略
nacos-provider: # 被调用的nacos中的服务名称
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
2.配置类
不能写在@SpringApplication注解的@CompentScan扫描得到的地方,否则自定义的配置类就会被所有的RibbonClients共享,不建议这么使用,推荐yaml方式
import com.alibaba.cloud.nacos.ribbon.NacosRule;
import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RibbonConfig {
/**
* 全局配置
*/
@Bean
public IRule iRule(){
//指定使用Nacos提供的负载均衡策略(优先调用统一集群的实例,基于随机权重)
return new NacosRule();
}
}
在主启动类上添加@RibbonClients注解
//配置多个 RibbonConfig 不能被@SpringApplication注解的@CompentScan扫描到,否则就是全局配置效果
//局部配置
@RibbonClients(value = {
@RibbonClient(name = "服务名称",configuration = RibbonConfig.class),
@RibbonClient(name = "服务名称",configuration = RibbonConfig.class)
})
// 使用全局的配置
//@RibbonClients(defaultConfiguration = RibbonConfig.class)
public class ManageApplication {
public static void main(String[] args) {
SpringApplication.run(ManageApplication.class,args);
}
}
自定义负载均衡策略需要继承 AbstractLoadBalancerRule 抽象类
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.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
/**
* 自定义一个权重负载均衡策略
*/
@Slf4j
public class MyWeightRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties discoveryProperties;
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
// 读取配置文件, 并且初始化, ribbon内部基本上用不上
}
/**
* 这个方法是实现负载均衡策略的方法
*
* @param
* @return
*/
@Override
public Server choose(Object key) {
try {
log.info("key:{}", key);
// 调用父类方法, 获取当前使用的负载均衡器
BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
// 获取当前服务的名称
String serviceName = baseLoadBalancer.getName();
/**
* namingService: 获取nacos的服务发现API
*/
NamingService namingService = discoveryProperties.namingServiceInstance();
/**
* 根据名称获取服务发现实例
* 在selectOneHealthyInstance中, nacos实现了权重的负载均衡算法
*/
Instance instance = namingService.selectOneHealthyInstance(serviceName);
return new NacosServer(instance);
} catch (NacosException e) {
e.printStackTrace();
}
return null;
}
}
2.启用自定义的负载均衡器应用
我们执行当前使用的负载均衡策略是自定义的权重负载均衡策略
import com.lxl.www.gateway.myrule.MyWeightRule;
import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class GlobalRibbonConfig {
@Bean
public IRule getRule() {
// 实现带有权重的负载均衡策略
return new MyWeightRule();
}
}
设置为全局配置GlobalRibbonConfig.class
//
//局部配置
/*@RibbonClients(value = {
@RibbonClient(name = "服务名称",configuration = RibbonConfig.class),
@RibbonClient(name = "服务名称",configuration = RibbonConfig.class)
})*/
// 使用全局的配置
@RibbonClients(defaultConfiguration = GlobalRibbonConfig.class)
public class ManageApplication {
public static void main(String[] args) {
SpringApplication.run(ManageApplication.class,args);
}
}
ribbon:
eager-load:
#开启ribbon饥饿加载
enabled: true
#配置服务使用ribbon饥饿加载,多个使用逗号分隔
clients: 服务名称1,服务名称2,服务名称3