RabbitMQ 负载均衡( 1 )

面对大量业务访问、高并发请求可以使用高性能的服务器来提升RabbitMQ服务的负载能力。当单机容量达到极限时,我们可以采取集群的策略来对负载能力做进一步的提升,但是这里还存在一个负载不均衡的问题。试想如果一个集群中有3个节点,那么所有的客户端都与其中的单个节点node1建立TCP连接,那么node1的网络负载必然会大大增加而显得难以承受,其他节点又由于没有那么多的负载而造成硬件资源的浪费,所以负载均衡显得尤为重要。

负载均衡(Load balance)是一种计算机网络技术,用于在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最佳资源使用、最大化吞吐率、最小响应时间以及避免过载的目的。使用带有负载均衡的多个服务器组件,取代单一的组件,可以通过冗余提高可靠性。负载均衡通常分为软件负载均衡和硬件负载均衡两种。

软件负载均衡是指在一个或者多个交互的网络系统中的多台放服务器上安装一个或多个相应的负载均衡软件来实现一种均衡负载技术。软件可以很方便的安装在服务器上,并且实现一定的均衡负载功能。软件负载均衡技术配置简单、操作也仿版,最重要的是成本很低。

硬件负载均衡是指在多台服务器间安装相应的负载均衡设备,也就是负载均衡器(如F5)来完成均衡负载技术,与软件负载均衡技术相比,能达到更好的负载均衡效果。由于硬件负载均衡技术需要额外的增加负载均衡器,成本比较高,所以适用于流量高的大型网站系统。

这里主要讨论的是如何有效的对RabbitMQ集群使用软件负载均衡技术,目前主流的方式有在客户端内部实现负载均衡,或者使用HAProxy、LVS等负载均衡软件来实现。

客户端内部实现负载均衡

对于RabbitMQ而言可以在客户端连接时简单的使用负载均衡算法来实现负载均衡。负载均衡算法有很多种,主流的有:

轮询法

将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关系服务器实际的连接数和当前的系统负载。

示例如代码清单所示,如果多个客户端需要连接到这个有3个节点的RabbitMQ集群,可以调用RoundRobin.getConnectionAddress()来获取相应的连接地址。

public class RoundRobin {
    private static List<String> list = new ArrayList<String>(){{
        add("192.168.0.2");
        add("192.168.0.3");
        add("192.168.0.4");
    }};
    private static int pos = 0;
    private static final Object lock = new Object();
    public static String getConnectionAddress(){
        String ip = null;
        synchronized (lock) {
            ip = list.get(pos);
            if (++pos >= list.size()) {
                pos = 0;
            }
        }
        return ip;
    }
}

随机法

通过随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。由概率统计理论可以得知,随着客户端调用服务端的次数增多,其实际效果越来越接近于平均分配调用量到后端的每一台服务器,也就是轮询的结果。对应的示例代码如下:

public class RandomAccess {
    private static List<String> list = new ArrayList<String>(){{
        add("192.168.0.2");
        add("192.168.0.3");
        add("192.168.0.4");
    }};
    public static String getConnectionAddress(){
        Random random = new Random();
        int pos = random.nextInt(list.size());
        return list.get(pos);
    }
}

源地址哈希法

源地址哈希的思想是根据获取的客户端IP地址,通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客户端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问。

public class IpHash {
    private static List<String> list = new ArrayList<String>(){{
        add("192.168.0.2"); add("192.168.0.3"); add("192.168.0.4");
    }};
    public static String getConnectionAddress() throws UnknownHostException {
        int ipHashCode = InetAddress.getLocalHost().getHostAddress().hashCode();
        int pos = ipHashCode % list.size();
        return list.get(pos);
    }
}

加权轮询法

不同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请求;而配置低、负载高的集群,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端。

加权随机法

与加权轮询法一样,加权随机法也根据后端机器的配置、系统的负载分配不同权重。不同的是,它是按照权重随机请求后端服务器,而非顺序。

最小连接数法

最小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有块有慢,它是根据后端服务器当前的连接情况,动态地选取其中当前积压连接数最少的一台服务器来处理当前的请求,尽可能地提高后端服务的利用效率,将负载合理地分流到每一台服务器。

有关于加权轮询法、加权随机法和最小连接数法的实现也比较简单,这里就留给读者自己动手实践一下。



相关文章

发表评论

Comment form

(*) 表示必填项

还没有评论。

跳到底部
返回顶部