Ribbon
是一套客户端负载均衡工具,Ribbon客户端组件提供一系列的完善的配置,如超时,重试等。
负载均衡器
服务端负载均衡
在消费者和提供者之间使用独立的代理进行负载,有硬件的如(h5),也有软件的如(Nginx,openResty)
下面就是根据Nginx来进行负载的,通过Nginx进行负载均衡,先发送请求,然后通过负载均衡算法,在多个服务器端选择一个进行访问,最后服务端在通过负载均衡算法进行分配
客户端负载均衡器
客户端根据自己的请求情况做负载均衡,Ribbon 就属于客户端自己做负载均衡
Nacos中使用Rabbion
nacos-discovery已经包含Ribbon的依赖,不需要再单独引入Ribbon
1. 添加@LoadBalanced注解
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
//注意需要添加@LoadBalanced注解
//作用:RestTemplate 就会把url上面的一级目录最为服务名,去注册中心找到对应的ip列表,
//根据算法使用其中一个ip+port
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
修改默认负载均衡策略
1. 使用其他规则
有三种方式
- 使用硬编码
//@RibbonClients(defaultConfiguration = MyRule.class) //全局设置负载规则,默认是轮询的
// @RibbonClient(name = "nacos-a", configuration = MyRule.class) //针对某个服务,特殊配置
@Configuration
public class RibbonConfig {
@Bean
public IRule myRule(){
//指定使用Nacos提供的负载均衡的策略
//return new NacosRule();
//使用随机策略
//return new RandomRule();
//轮询策略(默认策略)
return new RoundRobinRule();
//自己定义策略
//return new MyRule();
}
}
- 使用注解
@RibbonClient(name = "nacos-a", configuration = MyRule.class) //针对某个服务,特殊配置
@Configuration
public class RibbonConfig {
}
3.使用配置
# 这是Nacos-Discovery的配置,目的:项目启动后自动会把自己注册到Nacos server(ip+port)
# 约定注册的使用的名称就是spring.application.name,所以不需要配置name
spring.cloud.nacos.discovery.server-addr=192.168.11.20:8848
#配置具体某一个服务个性化规则
nacos-a.ribbon.NFLoadBalancerRuleClassName=com.by.rule.MyRule
logging.level.root = error
logging.level.com.by = debug
2.使用自己的规则
/**
* 自己写的策略
*/
public class MyRule extends AbstractLoadBalancerRule {
private static final Logger LOGGER = LoggerFactory.getLogger(NacosRule.class);
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
@Autowired
private NacosServiceManager nacosServiceManager;
//JUC包下,线程安装的Integer
private static AtomicInteger mun = new AtomicInteger(0);
private Server server = null;
@Override
@SneakyThrows
public Server choose(Object key) {
try {
String clusterName = this.nacosDiscoveryProperties.getClusterName();
String group = this.nacosDiscoveryProperties.getGroup();
DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer();
String name = loadBalancer.getName();
NamingService namingService = nacosServiceManager
.getNamingService(nacosDiscoveryProperties.getNacosProperties());
List<Instance> instances = namingService.selectInstances(name, group, true);
if (CollectionUtils.isEmpty(instances)) {
LOGGER.warn("no instance in service {}", name);
return null;
}
Instance maxInstance = instances.stream().max(Comparator.comparing(Instance::getWeight)).get();
Instance minInstance = instances.stream().min(Comparator.comparing(Instance::getWeight)).get();
int mun1 = mun.addAndGet(1);
if (mun1 % 5==0){
return new Server(minInstance.getIp(), minInstance.getPort());
}
return new Server(maxInstance.getIp(), maxInstance.getPort());
}
catch (Exception e) {
LOGGER.warn("NacosRule error", e);
return null;
}
}
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
}
}