Ribbon自定义负载均衡

news/2024/7/7 21:46:02 标签: java, ribbon, nginx, 分布式, spring cloud

自定义负载均衡

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

  • image-20201002090558925

  • 几个实现类,分别是

  • 抽象的负载均衡角色

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

  • image-20201002090921221

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

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

  • java">/*选择,如果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

  • java">@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 官方文档

  • https://www.springcloud.cc/spring-cloud-netflix.html
  • SpringCloud更新为SpringCloudNetflix,里面有记载自定义Ribbon的演示
  • image-20201002224854314
  • image-20201002225145511
  • 这里提示了,自定义的Ribbon客户端必须是Configuration,但是不能和主程序在同一级目录

自定义负载均衡实现

  • java">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注解

  • java">@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);
        }
    
    }
    
  • 启动类上指定自定义负载均衡


http://www.niftyadmin.cn/n/1699083.html

相关文章

人品比能力更重要---个人收藏

人品比能了更重要第1 忠诚——忠心者不遭解雇站在老板的立场上思考问题天天琢磨为公司赚钱与老板一起分享你的想法不卷入与老板对抗的势力忠心耿耿地维护公司的利益在诱惑面前经得住考验第2 敬业——每天必老板多做一小时工作的目的不仅仅在于报酬提供超出报酬的服务模糊“上班…

Feign接口方式实现

Feign Feign接口方式并没有成功&#xff0c;尝试了并没有成功 2020年10月16日再次尝试&#xff0c;成功&#xff0c;Success&#xff01; Feign的声明式的web service客户端&#xff0c;它让微服务之间调用更加简单&#xff0c;类似controller调用service&#xff0c;Spring…

asp.net button浏览器端事件和服务器端事件

OnClientClick&#xff1a;触发浏览器端的响应&#xff0c;OnClick触发服务器端响应; 在服务器aspx.cs脚本中设置按钮属性: this.btnTest.Attributes["OnClick"]"alert(hello);" 等同于OnClientClick。

LeetCode刷题——搜索(python语言)

LeetCode刷题——搜索&#xff08;python语言&#xff09; 一、搜索 搜索简单来说分为查找和遍历。 查找分为有序查找&#xff08;二分查找&#xff09;和无序查找&#xff08;顺序查找&#xff0c;二叉搜索树&#xff09;。 顺序查找&#xff1a;一个挨一个找&#xff0c;从…

狂神 Hystrix服务熔断

服务熔断 分布式系统面临的问题&#xff1a; 复杂的分布式体系结构中的应用 程序有数十个依赖关系&#xff0c;一个应用里面有多个功能&#xff0c;功能与功能之间有依赖关系&#xff0c;功能如果出现错误&#xff0c;产生等待&#xff0c;整条线就会卡死&#xff0c;服务熔断…

LeetCode刷题——排序(python语言)

LeetCode刷题——排序&#xff08;python语言&#xff09; 一、排序 顾名思义&#xff0c;排序就是将数组按照从小到大的顺序排列。 广义的排序分为内部排序方法和外部排序方法。 排序的方法有很多种&#xff0c;常用的冒泡、选择、插入、希尔、归并、快速、堆、计数、桶、基…

狂神SpringCloud 服务降级

服务降级 ​ 因为Feign项目的不成功&#xff0c;导致服务降级也无法完成 ​ 问题已解决&#xff0c;版本问题 根据实际业务情况以及流量&#xff0c;对一些服务喝页面有策略的不处理或换简单的方式处理&#xff0c;从而释放服务器资源以保证核心服务正常运作或高效运作使用场…

LeetCode刷题——动态规划(python语言)

LeetCode刷题——动态规划&#xff08;python语言&#xff09; 一、动态规划 1.1 基本概念 动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中&#xff0c;可能会有许多可行解。每一个解都对应于一个值&#xff0c;我们希望找到具有最优值的解。动态规划算法与…