【Java项目技术亮点】加权轮询负载均衡算法

写在前面:说实话,做分布式系统这些年,我见过太多人把负载均衡当成"随机分配"来用。3台服务器,A是8核32G,B和C是4核16G,如果平均分配流量,A只用了一半性能,B和C已经被压垮了。这就像公司分红------能力强的多分点,能力弱的少分点,而不是大家平分。这篇文章把加权轮询算法的原理、实现和踩坑经验整理出来,看完你就能手写一个Nginx同款平滑加权轮询。

文章目录


一、为什么需要加权轮询?

1.1 一个真实的线上场景

我们系统有3台应用服务器:

服务器 CPU 内存 权重
A 8核 32G 5
B 4核 16G 1
C 4核 16G 1

如果平均分配流量,A只用了一半性能,B和C已经被压垮了。

结果是:B和C频繁GC、响应变慢,甚至OOM,而A还在"摸鱼"。

1.2 加权轮询的核心价值

  1. 按能力分配:高性能服务器承担更多流量
  2. 资源利用率最大化:避免"旱的旱死,涝的涝死"
  3. 系统稳定性:防止低配服务器被压垮

1.3 生活类比:公司分红

公司年底分红,不可能大家平分。

业绩好的团队多分点,业绩一般的团队少分点。

加权轮询就是这个逻辑------按"能力"(权重)分配,而不是按"人头"平均分配。


二、轮询算法演进

2.1 四种算法对比

算法 实现复杂度 均匀度 是否考虑性能差异 适用场景
随机算法 一般 服务器性能相近
普通轮询 服务器性能完全相同
加权轮询 服务器性能不同
平滑加权轮询 极好 高并发,要求均匀

2.2 随机算法

java 复制代码
/**
 * 随机负载均衡
 * 简单但不均匀,可能连续命中同一台服务器
 */
public class RandomLoadBalance {
    private List<String> servers;
    private Random random = new Random();

    public RandomLoadBalance(List<String> servers) {
        this.servers = servers;
    }

    public String select() {
        int index = random.nextInt(servers.size());
        return servers.get(index);
    }
}

缺点:可能连续几次都选中同一台服务器,流量不均匀。

2.3 普通轮询

java 复制代码
/**
 * 普通轮询
 * 按顺序依次分配,不考虑服务器性能差异
 */
public class RoundRobinLoadBalance {
    private List<String> servers;
    private AtomicInteger index = new AtomicInteger(0);

    public RoundRobinLoadBalance(List<String> servers) {
        this.servers = servers;
    }

    public String select() {
        int current = index.getAndIncrement() % servers.size();
        return servers.get(current);
    }
}

缺点:A、B、C三台机器轮流分配,不管A是8核还是2核。


三、加权轮询原理

3.1 核心思想

总权重 = w1 + w2 + ... + wn

每个服务器的选中概率 = wi / 总权重

示例:

服务器A权重5,B权重1,C权重1,总权重 = 7。

  • A的选中概率 = 5/7 ≈ 71%
  • B的选中概率 = 1/7 ≈ 14%
  • C的选中概率 = 1/7 ≈ 14%

3.2 基于随机数的加权轮询实现

java 复制代码
import java.util.*;

/**
 * 基于随机数的加权轮询
 * 把权重映射到区间,随机数落在哪个区间就选哪个
 */
public class WeightedRandomLoadBalance {

    // 服务器列表
    private List<Server> servers;
    // 总权重
    private int totalWeight;
    // 随机数生成器
    private Random random = new Random();

    public WeightedRandomLoadBalance(List<Server> servers) {
        this.servers = servers;
        this.totalWeight = servers.stream().mapToInt(Server::getWeight).sum();
    }

    /**
     * 选择服务器
     * 思路:生成一个[0, totalWeight)的随机数,看它落在哪个区间
     */
    public Server select() {
        int randomValue = random.nextInt(totalWeight);
        int currentWeight = 0;

        for (Server server : servers) {
            currentWeight += server.getWeight();
            if (randomValue < currentWeight) {
                return server;
            }
        }
        // 兜底,理论上不会走到这里
        return servers.get(servers.size() - 1);
    }

    // 测试
    public static void main(String[] args) {
        List<Server> servers = Arrays.asList(
            new Server("A", "192.168.1.1", 5),
            new Server("B", "192.168.1.2", 1),
            new Server("C", "192.168.1.3", 1)
        );

        WeightedRandomLoadBalance lb = new WeightedRandomLoadBalance(servers);

        // 模拟1000次请求,统计每台服务器的选中次数
        Map<String, Integer> countMap = new HashMap<>();
        for (int i = 0; i < 1000; i++) {
            Server server = lb.select();
            countMap.merge(server.getName(), 1, Integer::sum);
        }

        System.out.println("=== 基于随机数的加权轮询结果 ===");
        countMap.forEach((name, count) -> 
            System.out.println(name + ": " + count + " 次 (" + (count * 100.0 / 1000) + "%)"));
    }
}

/**
 * 服务器节点
 */
class Server {
    private String name;
    private String ip;
    private int weight;

    public Server(String name, String ip, int weight) {
        this.name = name;
        this.ip = ip;
        this.weight = weight;
    }

    public String getName() { return name; }
    public String getIp() { return ip; }
    public int getWeight() { return weight; }

    @Override
    public String toString() {
        return name + "(" + ip + ", weight=" + weight + ")";
    }
}

运行结果示例:

复制代码
=== 基于随机数的加权轮询结果 ===
A: 713 次 (71.3%)
B: 145 次 (14.5%)
C: 142 次 (14.2%)

3.3 这个方案的缺陷

随机数方案的问题是:不均匀

短时间内可能连续选中A,也可能连续选中B。

高并发场景下,这种"抖动"会导致某台服务器瞬间被打满。


四、平滑加权轮询算法(Nginx算法)

4.1 算法原理

Nginx使用的平滑加权轮询算法,核心思想:避免短时间内流量集中在一台服务器

算法步骤(每轮):

  1. 当前权重 += 原始权重
  2. 选中当前权重最大的服务器
  3. 选中后,当前权重 -= 总权重

4.2 详细推演

初始状态:A权重5,B权重1,C权重1,总权重 = 7。

轮次 当前权重(加原始权重后) 选中 选中后当前权重
初始 0, 0, 0 - 0, 0, 0
第1轮 5, 1, 1 A(5最大) 5-7, 1, 1 = -2, 1, 1
第2轮 -2+5, 1+1, 1+1 = 3, 2, 2 A(3最大) 3-7, 2, 2 = -4, 2, 2
第3轮 -4+5, 2+1, 2+1 = 1, 3, 3 B(3最大,平局取第一个) 1, 3-7, 3 = 1, -4, 3
第4轮 1+5, -4+1, 3+1 = 6, -3, 4 A(6最大) 6-7, -3, 4 = -1, -3, 4
第5轮 -1+5, -3+1, 4+1 = 4, -2, 5 C(5最大) 4, -2, 5-7 = 4, -2, -2
第6轮 4+5, -2+1, -2+1 = 9, -1, -1 A(9最大) 9-7, -1, -1 = 2, -1, -1
第7轮 2+5, -1+1, -1+1 = 7, 0, 0 A(7最大) 7-7, 0, 0 = 0, 0, 0

7轮选中结果:A-A-B-A-C-A-A

A被选中5次(5/7),B被选中1次(1/7),C被选中1次(1/7)。

符合权重比例,且不会连续出现A-A-A这种情况!

4.3 完整Java实现

java 复制代码
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 平滑加权轮询负载均衡(Nginx算法)
 * 避免短时间内流量集中在一台服务器
 */
public class SmoothWeightedRoundRobin {

    // 服务器节点列表
    private List<Node> nodes;
    // 总权重
    private int totalWeight;

    public SmoothWeightedRoundRobin(List<Node> nodes) {
        this.nodes = new ArrayList<>(nodes);
        this.totalWeight = nodes.stream().mapToInt(Node::getWeight).sum();
    }

    /**
     * 选择服务器
     * 算法:每轮当前权重 += 原始权重,选最大的,选中后 -= 总权重
     */
    public synchronized Node select() {
        Node selected = null;
        int maxCurrentWeight = Integer.MIN_VALUE;

        for (Node node : nodes) {
            // 当前权重 += 原始权重
            node.currentWeight += node.weight;

            // 找当前权重最大的
            if (node.currentWeight > maxCurrentWeight) {
                maxCurrentWeight = node.currentWeight;
                selected = node;
            }
        }

        // 选中后,当前权重 -= 总权重
        if (selected != null) {
            selected.currentWeight -= totalWeight;
        }

        return selected;
    }

    /**
     * 打印当前状态(调试用)
     */
    public void printStatus() {
        StringBuilder sb = new StringBuilder("[");
        for (int i = 0; i < nodes.size(); i++) {
            sb.append(nodes.get(i).name).append("=").append(nodes.get(i).currentWeight);
            if (i < nodes.size() - 1) sb.append(", ");
        }
        sb.append("]");
        System.out.println(sb);
    }

    public static void main(String[] args) {
        List<Node> nodes = Arrays.asList(
            new Node("A", "192.168.1.1", 5),
            new Node("B", "192.168.1.2", 1),
            new Node("C", "192.168.1.3", 1)
        );

        SmoothWeightedRoundRobin lb = new SmoothWeightedRoundRobin(nodes);

        System.out.println("=== 平滑加权轮询详细过程 ===");
        System.out.println("初始权重:A=5, B=1, C=1,总权重=7");
        System.out.println();

        Map<String, Integer> countMap = new LinkedHashMap<>();
        countMap.put("A", 0);
        countMap.put("B", 0);
        countMap.put("C", 0);

        // 模拟14轮(2个周期)
        for (int i = 1; i <= 14; i++) {
            Node selected = lb.select();
            countMap.merge(selected.name, 1, Integer::sum);
            System.out.println("第" + String.format("%2d", i) + "轮:选中 " + selected.name + 
                ",当前状态:A=" + nodes.get(0).currentWeight + 
                ", B=" + nodes.get(1).currentWeight + 
                ", C=" + nodes.get(2).currentWeight);
        }

        System.out.println();
        System.out.println("=== 统计结果 ===");
        countMap.forEach((name, count) -> 
            System.out.println(name + ": " + count + " 次"));
    }

    /**
     * 节点内部类
     */
    static class Node {
        String name;
        String ip;
        int weight;        // 原始权重(不变)
        int currentWeight; // 当前权重(动态变化)

        public Node(String name, String ip, int weight) {
            this.name = name;
            this.ip = ip;
            this.weight = weight;
            this.currentWeight = 0;
        }

        public int getWeight() {
            return weight;
        }

        @Override
        public String toString() {
            return name + "(" + ip + ")";
        }
    }
}

运行结果:

复制代码
=== 平滑加权轮询详细过程 ===
初始权重:A=5, B=1, C=1,总权重=7

第 1轮:选中 A,当前状态:A=-2, B=1, C=1
第 2轮:选中 A,当前状态:A=-4, B=2, C=2
第 3轮:选中 B,当前状态:A=1, B=-4, C=3
第 4轮:选中 A,当前状态:A=-1, B=-3, C=4
第 5轮:选中 C,当前状态:A=4, B=-2, C=-2
第 6轮:选中 A,当前状态:A=2, B=-1, C=-1
第 7轮:选中 A,当前状态:A=0, B=0, C=0
第 8轮:选中 A,当前状态:A=-2, B=1, C=1
第 9轮:选中 A,当前状态:A=-4, B=2, C=2
第10轮:选中 B,当前状态:A=1, B=-4, C=3
第11轮:选中 A,当前状态:A=-1, B=-3, C=4
第12轮:选中 C,当前状态:A=4, B=-2, C=-2
第13轮:选中 A,当前状态:A=2, B=-1, C=-1
第14轮:选中 A,当前状态:A=0, B=0, C=0

=== 统计结果 ===
A: 10 次
B: 2 次
C: 2 次

4.4 为什么叫"平滑"?

对比两种算法在14轮中的选中序列:

算法 选中序列(14轮)
随机加权 A A A A A A A B A C A A B A(可能连续7个A)
平滑加权 A A B A C A A A A B A C A A(均匀分散)

平滑加权轮询把A的5次均匀分散到7轮中,不会连续集中在一台服务器

这就是"平滑"的含义------流量分配更均匀,没有突发峰值。

4.5 性能优化:去掉synchronized

上面的实现用了 synchronized,高并发下会成为瓶颈。

可以优化为原子操作版本

java 复制代码
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 无锁平滑加权轮询(高并发优化版)
 * 使用原子操作替代synchronized
 */
public class SmoothWeightedRoundRobinV2 {

    private Node[] nodes;
    private int totalWeight;

    public SmoothWeightedRoundRobinV2(Node[] nodes) {
        this.nodes = nodes;
        this.totalWeight = Arrays.stream(nodes).mapToInt(n -> n.weight).sum();
    }

    public Node select() {
        while (true) {
            // 复制当前状态
            int maxIndex = 0;
            int maxWeight = Integer.MIN_VALUE;

            for (int i = 0; i < nodes.length; i++) {
                // CAS尝试增加当前权重
                int current = nodes[i].currentWeight.get();
                int newWeight = current + nodes[i].weight;

                if (newWeight > maxWeight) {
                    maxWeight = newWeight;
                    maxIndex = i;
                }
            }

            // 对选中的节点做CAS扣减
            Node selected = nodes[maxIndex];
            int current = selected.currentWeight.get();
            int newWeight = current + selected.weight - totalWeight;

            if (selected.currentWeight.compareAndSet(current, newWeight)) {
                return selected;
            }
            // CAS失败则重试
        }
    }

    static class Node {
        String name;
        int weight;
        AtomicInteger currentWeight = new AtomicInteger(0);

        public Node(String name, int weight) {
            this.name = name;
            this.weight = weight;
        }
    }
}

踩坑提醒 :实际生产中,如果服务器数量不多(<100台),synchronized版本已经足够。过早优化是万恶之源,先保证正确性,再考虑性能。


五、Dubbo和Ribbon的加权轮询实现

5.1 Dubbo的RoundRobinLoadBalance

Dubbo的加权轮询就是基于Nginx的平滑加权轮询算法。

核心源码(简化版):

java 复制代码
public class RoundRobinLoadBalance extends AbstractLoadBalance {

    private static final class WeightedRoundRobin {
        private int weight;
        private AtomicLong current = new AtomicLong(0);
        private long lastUpdate;

        public void setWeight(int weight) {
            this.weight = weight;
            current.set(0);
        }

        public long increaseCurrent() {
            return current.addAndGet(weight);
        }

        public void sel(int total) {
            current.addAndGet(-1 * total);
        }
    }

    @Override
    protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
        // 核心逻辑:每个Invoker对应一个WeightedRoundRobin
        // 选中后 current -= totalWeight
        // 和Nginx算法完全一致
    }
}

Dubbo的特点:

  • 支持权重动态调整
  • 通过 lastUpdate 检测长时间未更新的节点,清理缓存
  • 默认预热机制:新启动的服务器权重逐渐提升到配置值

5.2 Ribbon的WeightedResponseTimeRule

Ribbon的实现思路不同------根据响应时间动态调整权重

java 复制代码
/**
 * Ribbon的WeightedResponseTimeRule核心逻辑
 * 响应时间越短,权重越高
 */
public class WeightedResponseTimeRule extends ClientConfigEnabledRoundRobinRule {

    // 计算每个服务器的权重
    void maintainWeights() {
        for (Server server : serverList) {
            // 获取平均响应时间
            double avgResponseTime = getAvgResponseTime(server);
            // 响应时间越短,权重越高
            // 权重 = maxResponseTime - avgResponseTime
            double weight = maxResponseTime - avgResponseTime;
            serverWeights.put(server, weight);
        }
    }
}

Ribbon vs Dubbo:

特性 Dubbo Ribbon
权重来源 配置(静态/动态) 响应时间(自动计算)
算法 平滑加权轮询 响应时间加权
动态调整 需手动配置或监听 自动根据RT调整
适用场景 已知服务器性能差异 性能差异不明显,需自适应

5.3 权重动态调整

实际生产中,权重不是一成不变的。

动态调整策略:

触发条件 调整动作
CPU使用率 > 80% 权重 -= 1
CPU使用率 < 30% 权重 += 1
平均响应时间 > 1s 权重 -= 2
错误率 > 5% 权重 = 0(下线)
服务恢复后 权重逐渐恢复(预热)
java 复制代码
/**
 * 简单的动态权重调整器
 */
public class DynamicWeightAdjuster {

    public void adjustWeight(ServerMetrics metrics, Node node) {
        double cpuUsage = metrics.getCpuUsage();
        double avgResponseTime = metrics.getAvgResponseTime();
        double errorRate = metrics.getErrorRate();

        int newWeight = node.getWeight();

        if (errorRate > 0.05) {
            newWeight = 0; // 错误率太高,下线
        } else if (cpuUsage > 0.8) {
            newWeight = Math.max(1, newWeight - 1);
        } else if (cpuUsage < 0.3 && avgResponseTime < 100) {
            newWeight = Math.min(node.getMaxWeight(), newWeight + 1);
        }

        node.setWeight(newWeight);
    }
}

六、踩坑指南

坑1:权重设置不合理导致某台服务器过载

我见过有人把A的权重设为100,B和C设为1。结果A扛了99%的流量,虽然A配置高,但瞬时流量峰值还是把它打垮了。权重要根据实际压测结果来设置,不是拍脑袋决定的。
坑2:服务器宕机后权重未及时调整

如果B宕机了,但负载均衡器不知道,还是按原权重分配。请求发到B就会超时。必须配合健康检查,宕机的服务器权重设为0,或者从列表中移除。
坑3:权重总和为0的边界情况

如果所有服务器权重都被调整为0,或者初始权重配置错误,select()方法会空转或者报错。代码里一定要有兜底处理:

java 复制代码
if (totalWeight <= 0) {
 throw new IllegalStateException("总权重不能为0");
}

坑4:平滑加权轮询的精度问题

整数运算在极端情况下可能产生精度问题。如果权重差异很大(比如A=10000,B=1),B可能长时间选不中。这种情况下建议对权重做归一化处理,或者使用双精度浮点数版本。


七、问题与解答

Q1:平滑加权轮询和普通加权轮询有什么区别?

A:

普通加权轮询(基于随机数或简单轮询)只保证长期统计符合权重比例。

平滑加权轮询保证每个小周期内都符合权重比例,避免短时间内流量集中。

示例: A权重5,B权重1,C权重1。

  • 普通轮询:可能连续7次都选中A(虽然概率低)
  • 平滑轮询:7轮内一定是A选5次,B选1次,C选1次,均匀分散

Q2:权重动态调整后,平滑轮询还能保证平滑吗?

A:

权重变化后,当前轮次可能短暂不平滑,但很快会进入新的平衡。

建议在权重变化时,重置所有节点的 currentWeight 为0,让算法重新进入稳定状态。

java 复制代码
public void updateWeight(String name, int newWeight) {
    for (Node node : nodes) {
        if (node.name.equals(name)) {
            node.weight = newWeight;
        }
        node.currentWeight = 0; // 重置
    }
    this.totalWeight = nodes.stream().mapToInt(n -> n.weight).sum();
}

Q3:加权轮询和一致性哈希有什么区别?

A:

维度 加权轮询 一致性哈希
目的 按权重分配流量 相同的key路由到相同节点
适用场景 无状态服务(API网关) 有状态服务(缓存、分片)
权重支持 原生支持 通过虚拟节点支持
节点变动影响 所有请求重新分配 只影响部分key

两者不是替代关系,而是适用场景不同。


八、面试高频考点汇总

考点1:常见的负载均衡算法有哪些?

答案:

  1. 随机:简单,但不均匀
  2. 轮询:按顺序分配,不考虑性能差异
  3. 加权轮询:按权重比例分配
  4. 平滑加权轮询:Nginx算法,均匀分散流量
  5. 最少连接:把请求发给当前连接数最少的服务器
  6. 源地址哈希:根据客户端IP哈希,保证同一客户端固定路由
  7. 一致性哈希:带虚拟节点,节点变动影响最小

考点2:Nginx的平滑加权轮询算法原理是什么?

答案:

每轮执行3步:

  1. 当前权重 += 原始权重
  2. 选中当前权重最大的服务器
  3. 选中后当前权重 -= 总权重

这样能保证权重比例正确,且流量均匀分散,不会连续集中在一台服务器。

考点3:加权轮询中,如果一台服务器宕机了怎么办?

答案:

  1. 配合健康检查,检测到宕机后将权重设为0
  2. 或者直接从服务器列表中移除
  3. 恢复后先给低权重,逐渐预热到正常权重
  4. 避免"一惊一诈":连续多次健康检查失败才判定宕机

考点4:Dubbo的负载均衡有哪些?默认是什么?

答案:

Dubbo内置4种负载均衡:

  1. RandomLoadBalance:随机(默认)
  2. RoundRobinLoadBalance:平滑加权轮询
  3. LeastActiveLoadBalance:最少活跃调用数
  4. ConsistentHashLoadBalance:一致性哈希

默认是随机,但可以通过 <dubbo:reference loadbalance="roundrobin" /> 切换。

考点5:加权轮询的权重一般怎么设置?

答案:

  1. 根据硬件配置:CPU核心数、内存大小
  2. 根据压测结果:每台服务器的实际QPS承载能力
  3. 动态调整:根据实时监控(CPU、内存、响应时间)自动调整
  4. 业务划分:核心服务给高配机器更高权重

九、模拟面试官提问和参考答案

场景题1:手写一个平滑加权轮询算法

参考答案:

java 复制代码
public class SmoothWeightedRoundRobin {
    private List<Node> nodes;
    private int totalWeight;

    public SmoothWeightedRoundRobin(List<Node> nodes) {
        this.nodes = nodes;
        this.totalWeight = nodes.stream().mapToInt(Node::getWeight).sum();
    }

    public synchronized Node select() {
        Node selected = null;
        int maxWeight = Integer.MIN_VALUE;

        for (Node node : nodes) {
            node.currentWeight += node.weight;
            if (node.currentWeight > maxWeight) {
                maxWeight = node.currentWeight;
                selected = node;
            }
        }

        selected.currentWeight -= totalWeight;
        return selected;
    }
}

关键点:currentWeight动态变化,选中后减去总权重,保证平滑。

场景题2:系统有4台服务器,权重分别是3、2、2、1,前10次请求分别发给谁?

参考答案:

总权重 = 8。

推演过程:

轮次 加权重后 选中 选中后
1 3,2,2,1 A -5,2,2,1
2 -2,4,4,2 C -2,4,-4,2
3 1,6,-2,3 B 1,-2,-2,3
4 4,0,0,4 A -4,0,0,4
5 -1,2,2,5 D -1,2,2,-3
6 2,4,4,-2 C 2,4,-4,-2
7 5,6,-2,-1 B 5,-2,-2,-1
8 8,0,0,0 A 0,0,0,0
9 3,2,2,1 A -5,2,2,1
10 -2,4,4,2 B -2,-4,4,2

前10次:A、C、B、A、D、C、B、A、A、B

场景题3:加权轮询和最少连接算法,分别适用于什么场景?

参考答案:

  • 加权轮询:适用于请求处理时间相近的场景(如REST API)。只考虑服务器性能差异,不考虑当前负载。

  • 最少连接:适用于请求处理时间差异大的场景(如文件上传下载)。即使A配置高,如果A当前连接数已满,新请求也会发给B。

实际生产中可以结合:先用加权轮询预选,再过滤掉连接数过多的节点。

场景题4:如何在加权轮询中实现"慢启动"(新节点逐步接收流量)?

参考答案:

新节点上线时,不直接给全量权重,而是逐步提升:

java 复制代码
public void warmUp(Node node) {
    int targetWeight = node.getMaxWeight();
    // 每30秒提升一次权重
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    executor.scheduleAtFixedRate(() -> {
        if (node.getWeight() < targetWeight) {
            node.setWeight(node.getWeight() + 1);
        } else {
            executor.shutdown();
        }
    }, 0, 30, TimeUnit.SECONDS);
}

Dubbo内置了预热逻辑,根据启动时间自动计算预热权重。

场景题5:如果服务器权重差异很大(A=100,B=1),平滑轮询会有什么问题?

参考答案:

  1. B选中间隔长:101轮中B只选1次,如果B在这101轮内宕机了,负载均衡器可能很久才发现
  2. 健康检查延迟:权重低的节点故障发现慢
  3. 精度问题:整数运算可能产生累积误差

解决方案:

  • 权重归一化,控制最大差异(比如不超过10倍)
  • 独立的健康检查机制,不依赖选中频率
  • 使用浮点数版本提高精度

十、互动话题

你们项目用的负载均衡算法是什么?有没有遇到过因为权重设置不合理导致的生产事故?欢迎在评论区分享你的经历,咱们一起聊聊负载均衡的"玄学"。


十一、参考资料

  1. Nginx官方源码 - ngx_http_upstream_round_robin.c
  2. Dubbo官方文档 - 负载均衡
相关推荐
灯厂码农1 小时前
C语言动态内存分配完全指南(malloc、calloc、realloc、free)
java·c语言·算法
梦梦代码精2 小时前
电商系统不是技术堆叠:LikeShop如何用分层Hold住复杂业务?
java·docker·代码规范
凯瑟琳.奥古斯特2 小时前
K次取反最大化数组和解法(力扣1005)
开发语言·c++·算法·leetcode·职场和发展
负责的蛋挞3 小时前
异步HttpModule的实现方式
java·服务器·前端
AC赳赳老秦3 小时前
防火墙规则批量配置实战:OpenClaw 自动生成模板、批量下发与合规性校验全解析
java·开发语言·人工智能·python·github·php·openclaw
Jerry3 小时前
LeetCode 203. 移除链表元素
算法
Tian_Hang3 小时前
Eclipse Ditto 物模型相关代码
java·运维·服务器·ide·eureka·eclipse
地平线开发者3 小时前
征程 6 | 工具链 QAT ObserverBase 源码解析
算法