Ribbon负载均衡

Ribbon负载均衡@[Mr_Wzzzz]

记录周阳老师的Spring Cloud教程,Ribbon目前已经进入维护模式,未来可以用LoadBalancer来替换

Ribbon简介

Ribbon是基于Netfix Ribbon实现的一套基于客户端的负载均衡工具,是Netfix 发布的开源项目,主要功能是为客户端提供软件负载均衡算法和服务调用,它提供了一系列完善的配置项如超时连接、重试等等。就是在配置文件中列出LoadBalance后面所有的机器,Ribbon会帮你基于某种规则(轮询,随机)去连接这些机器。

LB负载均衡(Load Balance)是什么

负载均衡就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)。常用的负载均衡软件有Nginx,LVS,硬件F5等。

Ribbon本地负载均衡客户端和Nginx服务端负载均衡的区别

Nginx是服务端负载均衡,客户端的所有请求都会交给Nginx,然后由Nginx实现转发请求。即负载均衡是由服务端完成的(集中式LB)
Ribbon本地负载均衡,在调用微服务的时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地从而在本地实现RPC远程服务调用技术(进程内LB)

Ribbon自带的负载均衡算法

RoundRobinRule(轮询算法)

遍历服务列表,轮询的选择Server

RandomRule(随机算法)

随机选择一个Server

RetryRule

对选定的负载均衡策略上重试机制。

WeightedResponseTimeRule

根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。

AvailabilityFilteringRule

过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值)

BestAvailableRule

选择一个最小的并发请求的server

ZoneAvoidanceRule

复合判断server所在区域的性能和server的可用性选择server

负载均衡算法原理

负载均衡算法:rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标,每次服务从重启后rest接口计数从1开始
List instances = discoveryClient.getInstances(“CLOUD-PAYMENT-SERVICE”)
如:
List[0] instances = 172.0.0.1:8002
List[1] instances = 172.0.0.1:8001

8001+8002组合为集群,他们共计两台机器,集群总数为2,按照轮询算法:
请求总数为1时:1 % 2 = 1 对应下标为1,则获得服务地址:172.0.0.1.8001
请求总数为2时:2 % 2 = 0 对应下标为0,则获得服务地址:172.0.0.1.8002
请求总数为3时:3 % 2 = 1 对应下标为1,则获得服务地址:172.0.0.1.8001
请求总数为4时:4 % 2 = 1 对应下标为1,则获得服务地址:172.0.0.1.8002
以此类推…

轮询算法源码

package com.netflix.loadbalancer;

import com.netflix.client.config.IClientConfig;
………………………………
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * The most well known and basic load balancing strategy, i.e. Round Robin Rule.
 */
public class RoundRobinRule extends AbstractLoadBalancerRule {

   	………………………………

    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) {
            //获得还活着的健康的服务实例(机器)即可达的,也就是Status为up的实例
            List<Server> reachableServers = lb.getReachableServers();
            //获取所有服务实例,无论是死是活,只要注册进服务中心即可
            List<Server> allServers = lb.getAllServers();
            //Status为up的服务实例数量
            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;
            }

            //调用服务器位置下标 = incrementAndGetModulo(服务器集群总数)
            int nextServerIndex = incrementAndGetModulo(serverCount);
            server = allServers.get(nextServerIndex);//根据下标获取服务实例

            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;
    }

    /**
     * Inspired by the implementation of {@link AtomicInteger#incrementAndGet()}.
     *
     * @param modulo The modulo to bound the value of the counter.
     * @return The next value.
     */
    private int incrementAndGetModulo(int modulo) {
        for (;;) {
            int current = nextServerCyclicCounter.get();
            int next = (current + 1) % modulo;
            if (nextServerCyclicCounter.compareAndSet(current, next))
                return next;
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值