SpringCloud Alibaba之Ribbon 修改和自定义负载均衡策略

Ribbon 简介

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的默认配置

**
使用ribben默认配置只需要定义一个RestTemplateBean并在方法上加上**@LoadBalanced** 的注解就可以使用了,默认负载均衡机制为轮训

    @Bean
    @LoadBalanced   //ribbon的负载均衡注解
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

**

Ribbon的 负载均衡策略

在这里插入图片描述

**
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 抽象类

  1. 自定义一个带有权重的负载均衡器MyWeightRule
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
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值