三种简单负载均衡

轮询法

轮询法是一种简单的负载均衡算法,它将请求依次分配给不同的主机。例如,如果有三个主机 A、B、C,那么第一个请求将被分配给主机 A,第二个请求将被分配给主机 B,第三个请求将被分配给主机 C,第四个请求将被分配给主机 A,以此类推。

具体讲解代码如下

public class RoundRobinLoadBalancer {
    private List<String> hosts; // 主机列表
    private AtomicInteger counter = new AtomicInteger(0); // 计数器

    public RoundRobinLoadBalancer(List<String> hosts) {
        this.hosts = hosts;
    }

    public String getNextHost() {
        int index = counter.getAndIncrement() % hosts.size(); // 计算应该被分配的主机
        return hosts.get(index);
    }
}

这是通过轮询的方式进行随机主机的获取,其中hosts是一个主机的集合,counter是一个原子计数器(也可以使用一个成员变量counter),初始值为0,通过其索引进行获取,这里的索引得到的方式久比较巧妙了,有以下几点:

  • 把counter提成成员变量counter就会变成1,2,3,...,n

  • 每一次接口访问counter都+1,保证下次不会访问当前的host

  • counter%size的值只会是0到size-1之间(不会越过Hosts的索引)

在这个示例中,我们定义了一个 RoundRobinLoadBalancer 类,它包含一个主机列表 hosts 和一个计数器 counter。getNextHost() 方法每次被调用时,会根据计数器的值选择一个主机,并将计数器加一。如果计数器的值超过了主机数量,就会重新从 0 开始计数。使用 AtomicInteger 类型的计数器可以保证线程安全。


随机法

随机法是一种随机分配请求的负载均衡算法,它将请求随机分配给不同的主机。例如,如果有三个主机 A、B、C,那么每个请求都有 1/3 的概率被分配给主机 A、B 或 C。

具体讲解代码如下

public class RandomLoadBalancer {
    private List<String> hosts; // 主机列表
    private Random random = new Random(); // 随机数生成器

    public RandomLoadBalancer(List<String> hosts) {
        this.hosts = hosts;
    }

    public String getNextHost() {
        int index = random.nextInt(hosts.size()); // 随机选择一个主机
        return hosts.get(index);
    }
}

在这个示例中,我们定义了一个 RandomLoadBalancer 类,它包含一个主机列表 hosts 和一个随机数生成器 random。getNextHost() 方法每次被调用时,会随机选择一个主机,并返回它的名称。使用 Random 类型的随机数生成器可以保证每次选择的主机是随机的。


最少连接法

最少连接法是一种根据当前连接数分配请求的负载均衡算法,它将请求分配给当前连接数最少的主机。例如,如果有三个主机 A、B、C,那么如果主机 A 当前连接数最少,那么下一个请求将被分配给主机 A。

具体讲解代码如下

public class LeastConnectionsLoadBalancer {
    private List<String> hosts; // 主机列表
    private Map<String, Integer> connections = new HashMap<>(); // 连接数映射表

    public LeastConnectionsLoadBalancer(List<String> hosts) {
        this.hosts = hosts;
        for (String host : hosts) {
            connections.put(host, 0); // 初始化连接数为 0
        }
    }

    public synchronized String getNextHost() {
        String host = null;
        int minConnections = Integer.MAX_VALUE;
        for (String h : hosts) {
            int connections = this.connections.get(h);
            if (connections < minConnections) {
                minConnections = connections;
                host = h;
            }
        }
        // 将选中的主机连接数加一
        int currentConnections = this.connections.get(host) + 1;
        this.connections.put(host, currentConnections);
        return host;
    }

    public synchronized void releaseConnection(String host) {
        // 将指定主机的连接数减一
        int currentConnections = this.connections.get(host) - 1;
        this.connections.put(host, currentConnections);
    }
}

在这个示例中,我们定义了一个 LeastConnectionsLoadBalancer 类,它包含一个主机列表 hosts 和一个连接数映射表 connections。getNextHost() 方法每次被调用时,会遍历所有主机,选择当前连接数最少的主机,并将其连接数加一。releaseConnection() 方法用于释放连接时,将指定主机的连接数减一。使用 synchronized 关键字可以保证线程安全。

posted @   uuuu-zhang  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示