Ribbon自定义负载均衡

自定义负载均衡

  • loadblancer负载均衡包下有一个IRule接口

  • image-20201002090558925

  • 几个实现类,分别是

  • 抽象的负载均衡角色

    • 获取负载均衡的默认实现
  • 可过滤角色

  • image-20201002090921221

  • public class RoundRobinRule extends AbstractLoadBalancerRule {
    
  • 轮询是比较常用的负载均衡算法,集成于AbstractLoadBalancerRule,所以基于这个来模仿一个自定义负载均衡

  • 几个会用到的源码的方法,获取服务个数,下一个服务

  • /*选择,如果lb为空,没有负载均衡*/
    public Server choose(ILoadBalancer lb, Object key) {
        if (lb == null) {
            log.warn("no load balancer");
            return null;
        }
    
        Server server = null;
        int count = 0;
        while (server == null && count++ < 10) {
            List<Server> reachableServers = lb.getReachableServers();
            /*获取可达到的服务*/
            List<Server> allServers = lb.getAllServers();
            /*获取所有服务*/
            int upCount = reachableServers.size();
            /*大小*/
            int serverCount = allServers.size();
            
    
            if ((upCount == 0) || (serverCount == 0)) {
                log.warn("No up servers available from load balancer: " + lb);
                /*没有服务能轮询*/
                return null;
                
            int nextServerIndex = incrementAndGetModulo(serverCount);
           	server = allServers.get(nextServerIndex);
            /*下一个服务*/
    
  • 先测试使用它预设的Rule

  • @SpringBootApplication
    @EnableEurekaClient
    public class Demo03consumerApplication {
        @Bean
        @LoadBalanced
        public RestTemplate getTestTemplate(){
            return new RestTemplate();
        }
    
        @Bean
        public IRule iRule(){
            return new RandomRule();
        }
    
        public static void main(String[] args) {
            SpringApplication.run(Demo03consumerApplication.class, args);
        }
    
    }
    
  • 之后负载均衡就变成RandomRule了

SpringCloud Netflix 官方文档

自定义负载均衡实现

  • package com.haoyun.config;
    
    
    import com.netflix.client.config.IClientConfig;
    import com.netflix.loadbalancer.AbstractLoadBalancerRule;
    import com.netflix.loadbalancer.ILoadBalancer;
    import com.netflix.loadbalancer.Server;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.List;
    
    /**
     * @author haoyun
     */
    
    @Configuration
    public class MyRibbonRule extends AbstractLoadBalancerRule {
    
    
        int total = 0;
        int reachableServersIndex = 0;
    
        /*选择,如果lb为空,没有负载均衡*/
        public Server choose(ILoadBalancer lb, Object key) {
            if (lb == null) {
                return null;
            }
    
            Server server = null;
    
            while (server == null) {
    
                List<Server> reachableServers = lb.getReachableServers();
                /*获取可达到的服务*/
                List<Server> allServers = lb.getAllServers();
                /*获取所有服务*/
                int upCount = reachableServers.size();
                /*存活服务总数*/
                int serverCount = allServers.size();
                /*服务总数*/
    
                if ((upCount == 0) || (serverCount == 0)) {
                    /*没有服务能轮询*/
                    return null;
                    /*upCount ServerCount有一个为0直接返回null*/
                }
    
                /*每个服务使用3次,做一个计数
                 * 做一个界限判定*/
                if (total < 3 && reachableServersIndex < upCount) {
                    server = allServers.get(reachableServersIndex);
                    for (int i = 0; i < allServers.size(); i++) {
                        System.out.println(allServers.get(i) + "============" + i);
                    }
                    /*下一个服务*/
                    System.out.println(total + "===================");
                    total++;
                    if (total == 3) {
                        System.out.println(reachableServersIndex);
                        reachableServersIndex++;
                    }
                } else {
                    total = 0;
                    if (reachableServersIndex == upCount) {
                        reachableServersIndex = 0;
                    }
                }
    
                if (server == null) {
                    /* Transient. */
                    Thread.yield();
                    continue;
                }
    
                if (server.isAlive() && (server.isReadyToServe())) {
                    return (server);
                }
    
                // Next.
                server = null;
            }
    
    
            return server;
        }
    
    
        @Override
        public Server choose(Object key) {
            return choose(getLoadBalancer(), key);
        }
    
        @Override
        public void initWithNiwsConfig(IClientConfig clientConfig) {
        }
    }
    
  • 加入Configuration注解

  • @SpringBootApplication
    @EnableEurekaClient
    @RibbonClient(name = "springCloud-provider" ,configuration = MyRibbonRule.class)
    /*在微服务启动时去加载自定义的Ribbon类*/
    public class Demo03consumerApplication {
        @Bean
        @LoadBalanced
        public RestTemplate getTestTemplate(){
            return new RestTemplate();
        }
    
        //@Bean
        //public IRule iRule(){
        //    return new RandomRule();
        //}
    
        public static void main(String[] args) {
            SpringApplication.run(Demo03consumerApplication.class, args);
        }
    
    }
    
  • 启动类上指定自定义负载均衡

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值