• SpringCloudAliBaba篇(三)之Ribbon负载均衡器


    1、什么是Ribbon

    目前主流的负载均衡大致有以下两种

    • 服务端的负载均衡,比如nginx
    • 客户端的负载均衡,Ribbon就属于客户端自己做负载均衡

    Spring Cloud Ribbon是基于Netflix实现的一套客户端的负载均衡工具,Ribbon客户端组件提供一系列的完善的配置,如超时、重试等,通过Load Balancer获取到服务提供的所有机器实例,Ribbon会自动基于某种规则(轮询、随机)去调用这些服务。Ribbon也可以实现我们自己的负载均衡算法。

    1.1、客户端的负载均衡

    例如spring cloud中的ribbon,客户端会有一个服务器地址列表,在发送请求前通过负载均衡算法选择一个服务器,然后进行访问,这是客户端负载均衡,即在客户端就进行负载均衡算法分配

    48

    1.2、服务端的负载均衡

    例如Nginx,通过nginx进行负载均衡,先发送请求,然后通过负载均衡算法,在多个服务器之间选择一个进行访问,即在服务器端进行负载均衡算法分配

    49

    1.3、常见的负载均衡算法

    • 随机,通过随机选择服务进行执行,一般这种方式使用较少
    • 轮询,负载均衡默认实现方式,请求来之后排队处理
    • 加权轮训,通过对服务器性能的分析,给高配置,低负载的服务器分配更高的权重,均衡各个服务器的压力
    • 地址Hash,通过客户端请求的地址的hash值取模进行服务器调度,ip hash
    • 最小连接数,即使请求均衡了,压力不一定均衡,最小连接数法就是根据服务器的情况,比如请求积压等参数,将请求分配到当前压力最小的服务器上,最小活跃数

    2、Nocos中使用Ribbon

    1、依赖

    nacos-discovery依赖了ribbon,可以不用再引入ribbon依赖

    50

    2、添加@LoadBanlanced注解

    @Configuration
    public class RestConfig{
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3、编写controller层即可调用

    @RestController
    @RequestMapping("/order")
    public class OrderController {
        @Autowired
        RestTemplate restTemplate;
        @GetMapping("/orderList")
        public String getOrder() {
            String message = restTemplate.getForObject("http://stock-server/stock/stockList", String.class);
            return "order" + message;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4、Ribbon的负载均衡策略

    51

    RandomRule:随机选择一个服务实例

    RoundRobinRule:轮询复杂均衡策略

    RetryRule:在轮询的基础上进行重试(没有超时的情况下)

    WeightedResponseTimeRule:自动计算权重(如果一个服务的平均响应时间越短权重越大,被选中执行任务的概率就越大)

    BestAvailableRule:过滤掉失效的服务实例的功能,然后顺便找出并发请求最小的服务器实例来使用

    ZoneAvoidanceRule:默认规则,根据服务所在区域的性能和服务的可用性选择服务器

    5、修改默认负载均衡策略

    • 方式一

    配置类的方式:

    @Configuration
    public class RibbonConfig {
        /**
         * 指定负载均衡策略
         */
        @Bean
        public IRule iRule(){
            // Nacos提供的负载均衡策略(优先调用同一集群下的实例,基于随机权重)
            return new NacosRule();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意:配置类不能写在@SpringbootApplication注解的@CompentScan扫描的到的地方,否则自定义的配置类就会被所有的RibbonClients共享,所以可放在其他目录下

    52

    策略配置好了,最后利用@RibbonClient指定微服务及其负载均衡策略

    53

    测试效果:(l两个提供者(9002,9003),一个消费者9001)

    54

    nacos注册中心可以看到,我们的实例都成功注册了进来

    55

    浏览器进行访问:

    56

    随着不断刷新,根据随机权重选择不同的服务。

    • 方式二:(配置文件的方式)

    修改application.yml

    57

    启动即可。

    6、自定义负载均衡

    继承AbstractLoadBalancerRule即可,比如挨个每个访问5次

    public class MyRibbonConfig extends AbstractLoadBalancerRule {
        /**
         * 默认等于0,如果等于5,指向下一个服务
         */
        private int total = 0;
        /**
         * 默认=0,如果total=5,currentIndex++
         */
        private int currentIndex = 0;
    
        public Server choose(ILoadBalancer lb, Object key) {
            if (lb == null) {
                return null;
            } else {
                Server server = null;
    
                while (server == null) {
                    if (Thread.interrupted()) {
                        return null;
                    }
                    //获得所有的服务
                    List<Server> upList = lb.getReachableServers();
                    //获得活着的服务
                    List<Server> allList = lb.getAllServers();
    
                    int serverCount = allList.size();
                    if (serverCount == 0) {
                        return null;
                    }
                    if (total < 5) {
                        server = upList.get(currentIndex);
                        total++;
                    } else {
                        total = 0;
                        currentIndex++;
                        if (currentIndex > upList.size()) {
                            currentIndex = 0;
                        }
                        server = upList.get(currentIndex);
    
                    }
    
                    if (server == null) {
                        Thread.yield();
                    } else {
                        if (server.isAlive()) {
                            return server;
                        }
    
                        server = null;
                        Thread.yield();
                    }
                }
    
                return server;
            }
        }
    
        protected int chooseRandomInt(int serverCount) {
            return ThreadLocalRandom.current().nextInt(serverCount);
        }
    
        @Override
        public Server choose(Object key) {
            return choose(getLoadBalancer(), key);
        }
    
        @Override
        public void initWithNiwsConfig(IClientConfig clientConfig) {
            // TODO Auto-generated method stub
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    注入我们自己写的负载均衡策略

    @Configuration
    public class RibbonConfig {
        /**
         * 指定负载均衡策略
         */
        @Bean
        public IRule iRule(){
            // Nacos提供的负载均衡策略(优先调用同一集群下的实例,基于随机权重)
            return new MyRibbonConfig();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    扩展

    开启饥饿加载,解决第一次调用慢的问题

    # 开启饥饿加载,解决第一次调用慢的问题
    ribbon:
      eager-load:
        enabled: true
        # 配置stock-server使用饥饿加载,多个的话用逗号分隔
        clients: stock-server
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    7、使用LoadBalancer替代Ribbon

    1、剔除依赖,既然不用ribbon自然要把依赖去除掉

    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!--添加loadbalancer依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2、如果不剔除,也可以在yml进行配置

    spring:
      application:
        name: order-server
      cloud:
        nacos:
        loadbalancer:
          ribbon:
            enable: false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3、配置完成后直接启动即可,将以轮询的策略进行访问。

  • 相关阅读:
    【初阶与进阶C++详解】第八篇:string类(标准库string类+string类模拟实现)
    R语言使用plot函数可视化数据散点图,通过xlim参数指定X轴的坐标范围(x axis limits)
    (保姆级)服务器-Zabbix6.0使用Python脚本实现带图片的邮箱的报警
    “非旺玖原装的PL2303,......“解决办法
    SpringBoot项目创建失败或无法启动,启动报错时的常见问题及解决方案
    Day25 Python的文件操作和异常处理
    Spring bean定义&Spring Bean 的作用域
    《C++ Primer》练习7.31:定义互相嵌套的类
    centos7安装confluence7.16.5
    [NISACTF 2022]checkin
  • 原文地址:https://blog.csdn.net/qijing19991210/article/details/125443798