• Ribbon自定义负载均衡策略算法Feign和RestTemplate


    原文链接:https://blog.csdn.net/weixin_40991408/article/details/103921299

    一. Ribbon 负载均衡策略介绍

    看图,不解释
    在这里插入图片描述
    默认 轮询

    二. Feign 更改负载均衡策略

    项目用 eureka-feign-hystrix-client,参考文章

    feign 更改负载就均衡策略 只要在配置文件 application.yml 配置就行,代码如下:

    server:
      port: 8767
    
    spring:
      #配置程序名为eureka-feign-hystrix-client
      application:
        name: eureka-feign-hystrix-client
    
    eureka:
      client:
        #服务注册地址
        serviceUrl:
          #注意: Eureka Server 的注册地址
          #将服务提供者注册到三个Eureka Server中去
          #defaultZone: http://peer1:8001/eureka/,http://peer2:8002/eureka/,http://peer3:8003/eureka/
          #defaultZone: http://peer1:8001/eureka/
          defaultZone: http://localhost:8761/eureka/
    
    feign:
      hystrix:
        enabled: true  #开启 Hystrix 功能
    
    logging:
      level:
        #feign 接口类的路径(这个配置表示的意思是,在调用 FeignHystrixInter 接口时做debug日志的输出。)
        com:
          example:
            eurekafeignhystrixclient:
              inter:
                FeignHystrixInter: debug
                # 如何配置多个 Feign 接口类 的 调用日志
                # FeignHystrixInter2: debug
                # FeignHystrixInter3: debug
                # FeignHystrixInter4: debug
    
    # Feign 如何结合 Ribbon 切换负载均衡策略算法
    eureka-client: # eureka-client 表示作用到哪个微服务
      ribbon:
        # NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #配置规则 随机
        # NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #配置规则 轮询
        # NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule #配置规则 重试
        # NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule #配置规则 响应时间权重
        # 我们也可以指定为其他策略,包括我们自己定义的,只要把相应的包路径写到这即可。
        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    
        # ConnectTimeout: 500 #请求连接超时时间
        # ReadTimeout: 1000 #请求处理的超时时间
        # OkToRetryOnAllOperations: true #对所有请求都进行重试
        # MaxAutoRetriesNextServer: 2 #切换实例的重试次数
        # MaxAutoRetries: 1 #对当前实例的重试次数
    

    三. RestTemplate 中更改负载均衡策略算法

    项目用 eureka-ribbon-hystrix-client,参考文章

    RestTemplate 更改负载就均衡策略 只要在Ribbon配置类 RibbonConfig 添加代码即可,代码如下:

    package com.example.eurekaribbonhystrixclient.config;
    
    import com.netflix.loadbalancer.IRule;
    import com.netflix.loadbalancer.RandomRule;
    import com.netflix.loadbalancer.RoundRobinRule;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    /**
     * 如何将RestTemplate 和 Ribbon 相结合进行负载均衡?
     * 只需要在程序的IOC容器中注入一个 RestTemplate 的 Bean,并在这个 Bean 上加上 @LoadBalanced 注解(负载均衡注解)
     * 此时 RestTemplate 就结合 Ribbon 开启了负载均衡功能
     *
     */
    
    @Configuration
    public class RibbonConfig {
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    
        /**
         * 更改 负载均衡策略算法
         * RandomRule #配置规则 随机
         * RoundRobinRule #配置规则 轮询
         * RetryRule #配置规则 重试
         * WeightedResponseTimeRule #配置规则 响应时间权重
         * 也可以自定义负载均衡策略的类
         * @return
         */
        @Bean
        public IRule myRule(){
            return new RandomRule();
        }
    }
    

    四.自定义负载均衡策略的类

    定义 MyCustomRule 类 继承 AbstractLoadBalancerRule 类,重写父类方法。
    例如:要求每台服务器被调用5次才能轮询下一个,也就是说以前每台机器一次,现在每台机器5次。代码如下:

    package com.example.eurekaribbonhystrixclient.rule;
    
    import com.netflix.client.config.IClientConfig;
    import com.netflix.loadbalancer.AbstractLoadBalancerRule;
    import com.netflix.loadbalancer.ILoadBalancer;
    import com.netflix.loadbalancer.Server;
    import java.util.List;
    import java.util.concurrent.ThreadLocalRandom;
    
    /**
     * 要求每台服务器被调用5次才能轮询下一个,也就是说以前每台机器一次,现在每台机器5次。
     */
    public class MyCustomRule extends AbstractLoadBalancerRule {
        @Override
        public void initWithNiwsConfig(IClientConfig iClientConfig) {
    
        }
    
        @Override
        public Server choose(Object key) {
            return choose(getLoadBalancer(), key);
        }
    
        /**
         * Randomly choose from all living servers
         */
        //@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
        //从服务清单中随机选择一个服务实例
        @SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
        public Server choose(ILoadBalancer lb, Object key) {
            if (lb == null) {
                return null;
            }
            Server server = null;
    
            int total = 0; // 总共被调用的次数,目前要求每台被调用5次
            int currentIndex = 0; // 当前提供服务的机器号
    
            while (server == null) {
                if (Thread.interrupted()) {
                    return null;
                }
                //负载均衡来获得可用实例列表upList和allList
                List<Server> upList = lb.getReachableServers();
                List<Server> allList = lb.getAllServers();
                int serverCount = allList.size();
                if (serverCount == 0) {
                    /*
                     * No servers. End regardless of pass, because subsequent passes
                     * only get more restrictive.
                     */
                    return null;
                }
                if (total < 5) {
                    server = upList.get(currentIndex);
                    total++;
                } else {
                    total = 0;
                    currentIndex++;
                    if (currentIndex >= upList.size()) {
                        currentIndex = 0;
                    }
                }
                if (server == null) {
                    /*
                     * The only time this should happen is if the server list were
                     * somehow trimmed. This is a transient condition. Retry after
                     * yielding.
                     */
                    Thread.yield();
                    continue;
                }
                if (server.isAlive()) {
                    return (server);
                }
                // Shouldn't actually happen.. but must be transient or a bug.
                server = null;
                Thread.yield();
            }
            //正常情况下,每次都应该可以选择一个服务实例
            return server;
        }
    
    
        //随机获取一个随机数
        protected int chooseRandomInt(int serverCount) {
            return ThreadLocalRandom.current().nextInt(serverCount);
        }
    
    }
    

    在Feign中 ,在配置文件application.yml 配置自定义的策略,如图所示:

    在这里插入图片描述

    在RestTemplate,配置自定义的策略,代码如下:

    package com.example.eurekaribbonhystrixclient.config;
    
    
    import com.example.eurekaribbonhystrixclient.rule.MyCustomRule;
    import com.netflix.loadbalancer.IRule;
    import com.netflix.loadbalancer.RandomRule;
    import com.netflix.loadbalancer.RoundRobinRule;
    import org.springframework.cloud.client.loadbalancer.LoadBalanced;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    /**
     * 如何将RestTemplate 和 Ribbon 相结合进行负载均衡?
     * 只需要在程序的IOC容器中注入一个 RestTemplate 的 Bean,并在这个 Bean 上加上 @LoadBalanced 注解(负载均衡注解)
     * 此时 RestTemplate 就结合 Ribbon 开启了负载均衡功能
     *
     */
    
    @Configuration
    public class RibbonConfig {
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    
        /**
         * 更改 负载均衡策略算法
         * RandomRule #配置规则 随机
         * RoundRobinRule #配置规则 轮询
         * RetryRule #配置规则 重试
         * WeightedResponseTimeRule #配置规则 响应时间权重
         * 也可以自定义负载均衡策略的类
         * @return
         */
        @Bean
        public IRule myRule(){
            return new MyCustomRule();//自定义的Rule
            //return new RandomRule();
        }
    }
  • 相关阅读:
    图标字体IcoMoon 使用
    JS 寻找孩子并打印路径
    为什么要用on()而不直接使用click
    setTimeout 虚假的“异步”
    解决Ajax.BeginForm还是刷新页面的问题
    .net生成Excel,并下载
    C#判断文件是否正在被使用
    sql为数字添加千分位(也就是钱的格式)
    HotelIInventory项目小结
    一步一步实现FormsAuthentic验证登录
  • 原文地址:https://www.cnblogs.com/fswhq/p/13572570.html
Copyright © 2020-2023  润新知