做后端好几年,经常被问到“单机架构怎么扛住上万并发”这种问题。说实话,第一次听到这个需求时我差点笑出来,正常思路不都是加机器吗?但仔细想想,问这个问题的人往往已经有了一台配置不错的物理机或云主机,预算有限,不想一上来就把架构搞成微服务加K8s。既然把范围限定在单机,那设计思路就不一样了,核心不是“有多少请求都能处理”,而是“在可控的资源占用下,最大化吞吐,并让请求快速完成”。
这篇文章我不打算空谈“单机可以扛十万并发”这种话,而是把设计路径拆开讲清楚。先给你一个结论:单机做到上万并发不仅可能,而且在特定业务场景下是常态。关键在于你的并发模型、IO处理方式、数据库访问路径,以及操作系统层面的参数配合。适合正在做高并发改造、又不想轻易引入分布式组件的团队参考,也适合刚接触后端性能优化的同学建立一套正确的判断框架。
1. 先拆解“上万并发”这个指标,别把并发和连接数搅浑
1.1 并发量的真实含义是什么
很多人把“并发”理解为同一时刻有多少请求打进来,其实更准确的说法是系统在单位时间内能处理的请求数,也就是QPS(每秒查询数),以及请求从进入到离开的平均耗时。这两个指标相乘,才是系统真正需要承载的活跃请求量。举例说明,如果接口平均耗时50毫秒,单机QPS是20000,那系统同一时刻的活跃请求数就是20000乘以0.05,等于1000个。这1000个同时存在的请求,才算真正意义上的并发数。
“上万并发”如果指的是上万个TCP连接同时保持在线,那这更多是连接管理问题。这种场景常见于推送服务、消息网关、IoT设备接入,瓶颈在网络层和连接状态维护,业务逻辑往往很轻。但如果“上万并发”指的是每秒处理上万次业务请求,那问题的难点就转移到了CPU计算、内存分配、数据库吞吐上。两种目标的设计思路完全不同,我建议你在动手前先把目标定义清楚,不然很容易被各种激进方案忽悠。
1.2 从数字倒推硬件和资源需求
我习惯用一个小公式估算资源:单机请求总量每秒QPS乘单次请求CPU耗时,可以得到所需CPU核心数的大致下限。举个例子,假设业务接口平均需要消耗20毫秒CPU时间,目标是20000 QPS,那需要的CPU计算量是20000乘0.02秒,等于400核秒每秒,也就是说至少需要400个CPU核心。这个数字对单机来说已经很大了。
这时候有两条路可以走。第一条是优化单次请求的CPU开销,把平均处理时间压到5毫秒以内,这样20000 QPS只需要100核左右,靠64核甚至128核的高端机器就能接近目标。第二条是接受不可控的消耗,转而通过缓存、异步化等手段降低真正落到核心计算链路上的请求比例,比如只有10%的请求需要做完整计算。这也是为什么很多号称高并发的系统,实际业务逻辑都很短,真正复杂的部分全部被挪到了离线处理或多级缓存里。所以单机上万并发不是无条件的,它更考验你对业务链路的瘦身能力。
1.3 从输入到响应的完整链路是分析重点
我一直跟团队强调一个原则:高并发设计不是只看应用服务本身,要看请求从客户端发出到服务端返回响应的整条链路上,每个环节是不是都可能成为瓶颈。我列举一下在单机架构里需要依次检查的点:
- 客户端到服务的网络连接建立成本
- 服务端的接入层IO模型与线程调度
- 业务代码里的CPU密集度与锁竞争
- 内存分配与垃圾回收或引用计数开销
- 数据库连接获取与执行计划
- 日志同步刷盘的IO等待
- 下游依赖的超时重试风暴
这些环节里任何一块成为短板,其他部分的优化效果都会被稀释。我见过一个项目,应用层做了很完善的协程改造,结果数据库还维持着100个连接的上限,请求全堵在获取连接上,最后测出来的压在QPS上表现平淡。所以请记住,单机高并发是木桶问题,不是某一层的炫技。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 并发模型选型:从线程到事件驱动再到协程的演进逻辑
2.1 线程池为什么很难支撑上万级并发
传统的Java后端是线程池模型,每个请求占用一个线程,线程内执行IO操作时整个线程都会阻塞等待。这种模型的优点是业务代码简单直白,缺点有两个方面。第一,线程本身要占据不小的内存,默认线程栈1MB,1000个线程光栈就得占1GB虚拟内存,实际换页压力也不小。第二,上下文切换是有代价的,当线程数量超过CPU核心数量成倍增长时,CPU的时间大量耗费在切换和调度上。
我测过一个典型的线程池接入服务,机器配置是32核,线程池开200线程时吞吐量还在增长,开到500线程后吞吐反而下降,平均延迟从30毫秒飙到150毫秒。线程池最佳工作线程数
