分布式架构下的负载均衡

向量数据库大数据云安全

大家好,我是苏三,又跟大家见面了。

前言

我之前在一家游戏公司,经历过单节点过载引发的全站崩溃,也处理过跨机房流量不均导致的区域性故障。

真正的负载均衡不是简单配置Nginx,而是构建全局流量调度中枢。

这篇文章跟大家一起聊聊负载均衡底层原理和常见问题,希望对你会有所帮助。

点击这里获取:100万QPS短链系统、商城微服务、苏三AI项目、秒杀系统、商城系统、秒杀系统、代码生成工具等 7 个项目的 源代码、开发教程和技术答疑

一、负载均衡四大层级架构

现代应用流量调度全景图

picture.image

各层核心作用

  1. DNS层 :实现地域级流量调度(如智能解析)
  2. LVS层 :基于IP的4层负载,千万级并发支撑
  3. Nginx层 :7层应用路由,支持HTTPS卸载
  4. 服务层 :客户端负载均衡(如Ribbon)
  5. 数据层 :数据库读写分离(如MyCAT)

二、五大负载算法

轮询算法(Round Robin)

实现原理

  
public class RoundRobinLoadBalancer {    
    privatefinal List<String> endpoints;    
    privatefinal AtomicInteger counter = new AtomicInteger(0);    
  
    public String next() {    
        int index = counter.getAndIncrement() % endpoints.size();    
        if (index < 0) {    
            counter.set(0);    
            index = 0;    
        }    
        return endpoints.get(index);    
    }    
}    

致命缺陷 :未考虑服务器性能差异 → 低配服务器先过载

加权轮询(Weighted Round Robin)

动态权重配置

picture.image

Nginx配置示例

  
upstream backend {    
    server 192.168.1.10 weight=3; # 30%流量    
    server 192.168.1.11 weight=7; # 70%流量    
    server 192.168.1.12 backup;   # 备用节点    
}    

最少连接算法(Least Connections)

核心思想 :将新请求分配给当前连接数最少的服务器picture.image

Java实现

  
public String leastConnections() {    
    return endpoints.stream()    
        .min(Comparator.comparingInt(this::getActiveConnections))    
        .orElseThrow();    
}    
  
// 模拟获取连接数(真实场景从监控获取)    
private int getActiveConnections(String endpoint) {    
    return connectionStats.getOrDefault(endpoint, 0);    
}    

一致性哈希(Consistent Hashing)

解决痛点 :分布式缓存扩容时大量缓存失效

picture.image

虚拟节点实现

  
public class ConsistentHash {    
    privatefinal SortedMap<Integer, String> circle = new TreeMap<>();    
    privatefinalint virtualNodes;    
  
    public void addNode(String node) {    
        for (int i = 0; i < virtualNodes; i++) {    
            String vNode = node + "#" + i;    
            int hash = hash(vNode);    
            circle.put(hash, node);    
        }    
    }    
  
    public String getNode(String key) {    
        if (circle.isEmpty()) returnnull;    
        int hash = hash(key);    
        SortedMap<Integer, String> tailMap = circle.tailMap(hash);    
        int nodeHash = tailMap.isEmpty() ? circle.firstKey() : tailMap.firstKey();    
        return circle.get(nodeHash);    
    }    
}    

自适应负载算法(AI预测)

动态预测模型

picture.image

关键指标

  
# 使用简单线性回归预测    
def predict\_load(historical):    
    # 输入: [(time, cpu, mem, conns)]    
    X = [t[0] for t in historical]    
    y = [t[1] * 0.6 + t[2] * 0.3 + t[3] * 0.1 for t in historical]    
    model = LinearRegression().fit(X, y)    
    return model.predict([[next\_time]])    

三、高可用负载架构设计

双活数据中心流量调度

picture.image

故障切换策略

  1. 网络层 :BGP Anycast实现IP级切换
  2. 应用层 :Nginx主动健康检查
  
server 192.168.1.10 max\_fails=3 fail\_timeout=30s;    

  1. 服务层 :Spring Cloud熔断降级
  
@HystrixCommand(fallbackMethod = "defaultResult")    
public String service() { /* ... */ }    

四、深度避坑指南

陷阱1:缓存穿透引发雪崩

场景 :某热点Key失效导致流量直击数据库

picture.image

解决方案

  
// 使用Google Guava缓存空值    
LoadingCache<String, Object> cache = CacheBuilder.newBuilder()    
    .maximumSize(1000)    
    .expireAfterWrite(30, TimeUnit.SECONDS)    
    .build(new CacheLoader<>() {    
        public Object load(String key) {    
            Object value = db.query(key);    
            return value != null ? value : NULL\_OBJ; // 空对象占位    
        }    
    });    

陷阱2:TCP连接复用失衡

现象 :长连接导致流量倾斜

picture.image

解决方案

  
# Nginx配置短连接    
upstream backend {    
    server 192.168.1.10;    
    keepalive 50; # 每worker最大连接数    
    keepalive\_timeout 60s;    
}    

陷阱3:跨机房延迟导致超时

案例 :北京调用上海服务频繁超时

picture.image

优化方案

  1. 路由策略 :优先同机房调用
  2. 超时配置
  
feign:    
  client:    
    config:    
      default:    
        connectTimeout: 500    
        readTimeout: 1000    

  1. 降级策略
  
// 上海服务不可用时使用本地缓存    
@Fallback(fallbackClass = LocalCacheService.class)    
public interface RemoteService {}    

五、自研负载均衡器核心设计

架构设计

picture.image

健康检查实现

  
public class HealthChecker implements Runnable {    
    privatefinal List<ServerNode> nodes;    
  
    public void run() {    
        for (ServerNode node : nodes) {    
            boolean alive = checkNode(node);    
            node.setAlive(alive);    
        }    
    }    
  
    private boolean checkNode(ServerNode node) {    
        try (Socket socket = new Socket()) {    
            socket.connect(new InetSocketAddress(node.getIp(), node.getPort()), 500);    
            returntrue;    
        } catch (IOException e) {    
            returnfalse;    
        }    
    }    
}    

总结

三层设计原则

picture.image

五大核心原则

  1. 冗余设计 :至少2个负载均衡节点形成集群
  2. 多级分流 :DNS+LVS+Nginx+服务层分级调度
  3. 动态调整 :基于实时指标自动更新权重
  4. 故障隔离 :快速剔除异常节点
  5. 灰度发布 :权重式流量切换

负载均衡的本质不是平均分配流量,而是让合适的请求到达合适的节点。

当你能从流量调度中看到业务特征,从算法选择中预见系统瓶颈,才算真正掌握了高并发架构的精髓。

最后

最后欢迎加入苏三的星球,你将获得:100万QPS短链系统、复杂的商城微服务系统、苏三AI项目、刷题吧小程序、秒杀系统、商城系统、秒杀系统、代码生成工具等8个项目的源代码、开发教程和技术答疑。

系统设计、性能优化、技术选型、底层原理、Spring源码解读、工作经验分享、痛点问题、面试八股文等多个优质专栏。

还有1V1修改简历、技术答疑、职业规划、送书活动、技术交流。

目前星球已经更新了5800+篇优质内容,还在持续爆肝中.....

星球已经被官方推荐了3次,收到了小伙伴们的一致好评。

戳我加入学习,已有1800+小伙伴加入学习。

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
字节跳动 XR 技术的探索与实践
火山引擎开发者社区技术大讲堂第二期邀请到了火山引擎 XR 技术负责人和火山引擎创作 CV 技术负责人,为大家分享字节跳动积累的前沿视觉技术及内外部的应用实践,揭秘现代炫酷的视觉效果背后的技术实现。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论