springcloud负载均衡采用一致性哈希算法

Posted heqiyoujing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springcloud负载均衡采用一致性哈希算法相关的知识,希望对你有一定的参考价值。

 

  spring cloud网关集成了zuul和熔断器,因此网关天生具有负载均衡和熔断的功能。因此spring cloud的负载均衡算法,就是ribbon的负载均衡算法。在ribbon中,负载均衡默认了轮询的方法。如果想采用一致性哈希算法,实现负载均衡,那应该怎么办呢?

  这里我才用guava的一致性哈希算法,就不自己写一致性哈希算法了。

  首先pom.xml:

<!--guava缓存cache-->
      <dependency>
          <groupId>com.google.guava</groupId>
          <artifactId>guava</artifactId>
          <version>23.0</version>
      </dependency>

  然后自己写一个类,集成AbstractLoadBalancerRule:


@Component
public class ConsistentHash extends AbstractLoadBalancerRule {

    private Logger log = LoggerFactory.getLogger(ConsistentHash.class);

    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;
            }
            //获取请求URI
            RequestContext ctx = RequestContext.getCurrentContext();
            HttpServletRequest request = ctx.getRequest();
            String URI = request.getServletPath()+"?"+request.getQueryString();

            int hashcode = URI.hashCode();
            int model = Hashing.consistentHash(hashcode, serverCount); //一致性哈希,直接返回第几个数

            server = allServers.get(model);

            if (server == null) {
                /* Transient. */
                Thread.yield();
                continue;
            }

            if (server.isAlive() && (server.isReadyToServe())) {
                return (server);
            }

            // Next.
            server = null;
        }

        if (count >= 10) {
            log.warn("No available alive servers after 10 tries from load balancer: "
                    + lb);
        }
        return server;



    }

    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(), key);
    }

    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
        // TODO Auto-generated method stub

    }

}

  就完成了。

  如果只是想针对某个应用实现一致性哈希负载均衡,那么可以以下几步:

  1.去掉ConsistentHash上面的注解

  2.新建一个类MyRibbonConfiguration:

public class MyRibbonConfiguration {
    @Bean
    public IRule ribbonRule() {
        return new ConsistentHash();//实例化与配置文件对应的策略类
    }
}

  3

@Configuration
@RibbonClient(name = "hello-service", configuration = MyRibbonConfiguration.class)
public class RibbonConfiguration {

}

  这样就只是针对hello-service进行一致性哈希负载均衡算法,其他 的还是采用轮询。

 

以上是关于springcloud负载均衡采用一致性哈希算法的主要内容,如果未能解决你的问题,请参考以下文章

一文搞懂负载均衡中的一致性哈希算法

一致性哈希算法---负载均衡

一致性哈希算法---负载均衡

一致性哈希算法---负载均衡

2016 -Nginx的负载均衡 - 一致性哈希 (Consistent Hash)

负载均衡-基础-一致性哈希算法及java实现