本文目录导读:
搭建一个支持十万并发的网络系统是一个典型的高并发、高可用架构设计问题,十万并发(100,000 QPS/TPS 或 100,000 个长连接)在互联网行业中属于中大型规模,需要从网络层、接入层、应用层、数据层以及基础设施五个维度进行系统性设计。
以下是一套经过行业验证的搭建思路和技术选型方案:
核心指标与瓶颈分析
在动手之前,先明确“十万并发”的具体场景:
- 十万 QPS(每秒请求数):常见于高流量 API、电商秒杀、热点新闻。
- 十万 TCP 长连接(C10K x10):常见于即时通讯、物联网、游戏服务器。
主要瓶颈通常出现在:
- Linux 内核参数: 文件描述符限制、TIME_WAIT 状态、TCP 缓冲区。
- 单机网络栈: 网卡中断处理能力、内存带宽。
- 连接池与线程模型: 数据库/Redis 连接数打满、线程上下文切换成本。
- 带宽: 出口带宽是否足够承载十万请求的响应体数据。
基础设施与网络层优化
这是支撑十万并发的物理基础。
-
硬件选型
- 网卡: 必须使用万兆网卡(10Gbps),甚至 40G/100G,并开启多队列(RSS/RPS)。
- CPU: 高频 CPU,核心数越多越好(32核以上),因为网卡中断会绑定到特定 CPU 核心。
- 内存: 至少 64GB 以上,用于承载 Socket 缓冲区(tcp_rmem/tcp_wmem)。
-
Linux 内核调优(关键)
- 修改文件句柄:
fs.file-max = 1000000,进程级nofile设为 655350。 - 减少 TIME_WAIT:
net.ipv4.tcp_tw_reuse = 1(用于客户端),net.ipv4.tcp_tw_recycle = 0(已废弃,不要用)。 - 增大端口范围:
net.ipv4.ip_local_port_range = 1024 65000。 - 开启 TCP Fast Open:
net.ipv4.tcp_fastopen = 3。 - 增大 backlog:
net.core.somaxconn = 65535。
- 修改文件句柄:
-
网络拓扑
- 使用 LVS(Linux Virtual Server) 或 F5 硬负载做四层负载均衡。
- BGP 多线接入 避免跨运营商延迟。
入口流量调度层
单台机器承载不了十万 QPS(即使性能很好,也建议在 8-10万 QPS 以下使用单机),必须做水平扩展。
-
DNS 轮询 + GSLB
多机房部署,通过智能 DNS 将用户分流到最近/负载最低的机房。
-
负载均衡器
- 四层(LVS/DPVS/F5): 吞吐量极高,直接转发 TCP 包,适合入门,LVS 单机可支撑 60万-100万 PPS(每秒包数)。
- 七层(Nginx/OpenResty/Envoy): 负责 HTTP 协议解析、限流、重试。单台 Nginx 经过调优可以支撑 2-5万 QPS,需要部署 3-5 台组成集群。
- 云原生网关: 阿里云 SLB、腾讯云 CLB 可以直接按需购买,自带高可用。
应用层架构设计
这是最核心的部分,决定了系统能否扛住压力。
-
无状态化 (Stateless)
所有 Web 服务器(Tomcat/SpringBoot/Go)不存储用户 Session,Session 集中存储在 Redis 或分布式 Session 中间件(如 Spring Session)。
-
协程/异步模型
- 语言选择: Go (Goroutine)、Java (Vert.x/WebFlux)、Node.js、Python (asyncio)。
- Java: 如果使用传统 Spring Boot + Tomcat,单个 Tomcat 默认线程池 200,需要调大
server.tomcat.max-threads=2000,但不推荐通过增加单机线程数来硬扛。 - 推荐: 使用 Netty(Java)或 Go 的 net/http 配合 IO 多路复用(epoll)。
-
连接池管理
- 数据库连接池(Druid/HikariCP): 原则:连接数少,效率高,100核的机器,数据库连接池设置 30-50 个即可,并发高时,请求排队等待远比创建新连接快。
- Redis 连接池: 同理,单机 Redis 实例一般建议连接数控制在 500 以内。
缓存与数据层解耦
十万 QPS 直接穿透到数据库(MySQL/PostgreSQL)几乎是必死的。
-
多级缓存
- 一级缓存: 本地缓存(Caffeine/Guava Cache),热点数据(如用户信息)在应用内存中缓存,响应时间 <1ms。
- 二级缓存: 分布式缓存(Redis Cluster/阿里云 Tair),抗住 90% 的读请求,一个 64G 内存的 Redis 集群分片可以轻松支撑 10万 QPS 读。
- 静态化/CDN: 对于不经常变化的数据(首页、图片),直接全量推送到 CDN。
-
数据库扩展
- 读写分离: 一主多从,主库负责写,从库分担读(可挂载 3-5 个从库)。
- 分库分表(Sharding): 当单表数据量超过 1000万行或单库 QPS 超过 5000 时,必须分片,常用方案:ShardingSphere、MyCAT、Vitess。
针对不同场景的具体方案示例
场景 A:十万 HTTP 请求/秒(API 服务)
- LB层: 2 台 LVS(主备) + 5 台 Nginx(做反向代理)。
- 应用层: 20 台 8核16G 的云服务器,部署 Go 或 Spring Boot + Netty。
- 缓存层: 1 个 Redis Cluster(6节点 3主3从),每秒缓存命中 9万次,穿透到 DB 1万次。
- 数据库: 4台 MySQL(1主3从),分别负载 2500 QPS 读/写。
场景 B:十万 TCP 长连接(IM/推送)
- 连接层: 使用 Netty 或 C++ 自研,每个连接占用约 3-6KB 内存,10万连接约占用 0.6-1.2GB 内存,瓶颈在于 CPU 中断和 epoll 复杂度。
- 架构: 一台 32核服务器即可稳定承载 10万长连接(通过 CPU 绑定、零拷贝技术)。
- 消息分发: MQ 中间件(Kafka/Pulsar)做削峰填谷,不能直接发推送,需通过 MQ 确认。
- 状态同步: 用户在线状态存储在 Redis 的 Bitmap 或 Hash 中,每秒同步一次。
压测与持续优化
架构搭好后,不能直接上线,必须压测。
- 压测工具: wrk、JMeter、Locust、GoReplay(回放生产流量)。
- 关键 QPS 指标: 接口延迟 P99 < 200ms。
- 常见排查命令:
ss -s:查看当前连接数、TIME_WAIT 状态。top/htop:看 CPU 瓶颈是否是软中断(si%)。dstat:看网卡吞吐量是否打满。perf top:看内核热点函数(如tcp_v4_rcv)。
最小可行方案
如果想搭建一个支持 10万 QPS 的 Web 系统:
- 购买云服务: 阿里云/腾讯云/华为云。
- 入口: 使用云厂的负载均衡 SLB/CLB(自带高可用)。
- 计算: 购买 10-15 台轻量级云服务器(4-8 核),部署无状态应用。
- 缓存: 购买一个 32G 的 Redis 集群。
- 数据库: 购买云 RDS(MySQL),开启只读实例。
- 排队: 使用 RocketMQ/Kafka 对写流量削峰。
最后一条准则: 在软件层面调优到极致之前,不要追求硬件堆叠,十万并发在 2025 年的云原生架构下,核心不在于“搭”,而在于把每一个请求的 IO(网络、磁盘、锁)消除或最小化。
标签: 负载均衡