先说说我这边的背景。前两年公司有个业务要上大促,业务方提了一个在我看来有点“不讲理”的需求:预算不批、集群不给,就一台物理机,要扛住上万并发。我当时第一反应是“又要马儿跑又要马儿不吃草”,但需求既然接了就得上。后来我把目标拆细、一层层做容量评估,发现单机在特定场景下做到上万并发并不是天方夜谭——前提是你得搞清楚到底要扛的是哪种“并发”。
如果现在有同学也要做这类单机高并发的方案设计,我的建议是别急着搜“高并发怎么办”然后背一堆中间件,先想清楚这几件事:并发指标怎么定义?业务是CPU密集还是IO密集?单机资源上限在哪里?这篇文章我就按我当时从目标拆解到落地压测的完整过程来写,尽量还原每个决策是怎么做的,哪些地方容易翻车,也会拿出实际可用的参数和配置,希望能给你省点弯路。
1. 先搞清楚“上万并发”到底是什么含义
1.1 并发连接数和请求吞吐是两码事
很多人聊“并发”的时候,会把连接数和QPS混在一起。实际上,这两个指标对应的工作压力完全不一样。
假设你的服务是长连接网关,比如WebSocket服务器或者IM消息推送入口,那么“上万并发”通常指在线连接数有1万个。每个客户端连着但大部分时间不发消息,这时候服务端大部分工作其实是维持连接、周期心跳。1万连接听着吓人,其实只要设计合理,普通的8核16G服务器就扛得住,真正吃CPU的反而是心跳包解析和广播推送。
但如果你说的“上万并发”是RPC接口每秒要处理1万次请求,那情况完全不同。这种短连接、高频请求的场景,服务端要处理的是网络报文拆包、路由分发、业务逻辑执行、结果序列化回包。照我经验,纯业务逻辑的前提下,一个8核机器要稳定跑到单实例上万QPS,不是不行,但对接口耗时和复杂度的要求非常严格,平均响应时间得控制在10毫秒以内,而且绝大部分请求不能触碰慢存储。
所以动手前第一件事就是把指标拆清楚,到底是Tps、Qps,还是同时在线连接数?我自己当时做方案汇报第一页就是画表,明确写目标值,免得测量口径不一致,后面扯皮。
1.2 单机资源上限的粗略估算
按我个人习惯,接到这种目标后,会先做一个粗颗粒度的容量估算。理论上可以做数学推导,但工程上更实用的办法是按“核心数x单核心处理能力”来估算。
单核CPU每秒能处理多少次简单请求,可以用这样一个粗账来算:假设每请求平均耗用1毫秒CPU时间(包含业务逻辑、序列化、网络读写),单核每秒理论极限是1000请求;一个8核的机器,理论极限就是8000QPS。要超过这个数,要么降低单请求平均CPU时间,要么靠多核并行,要么接受一定比例的排队。
IO密集场景另算。比如大部分时间是等待下游数据库返回,CPU那一毫秒可能只是发起调用和等待,那瓶颈就到了数据库连接数和网络RTT上。只要数据库能扛住,单机应用可以通过连接池和协程扛更多的并发请求,操作系统帮忙做IO等待调度。
我当时给自己定了个基本策略:先把无状态接口的单机撑到极限,再把所有涉及数据库、缓存的部分能挡就挡、能批量就批量,最后再回头优化可能产生线程阻塞的资源点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统层配置决定并发上限的天花板
2.1 文件句柄、端口和连接队列
很多项目代码写得没毛病,但压测到几千连接就报错,一查是操作系统层限制没放开。这类问题在本地开发环境根本暴露不出来,因为并发量太小。
第一道门槛是最大文件句柄数。Linux下一切皆文件,每个网络连接都对应一个文件描述符。系统默认的ulimit -n通常是1024,这点数量连一个像样的压测客户端都不够用,更别提服务端要接收上万个连接。
我当时在服务部署脚本里写死了这几行配置,直接改/etc/security/limits.conf和sysctl.conf,这里贴出来给需要的人参考:
bash复制# /etc/security/limits.conf
* soft nofile 1048576
* hard nofile 1048576
* soft nproc 131072
* hard nproc 131072
再有就是TCP层的内核参数。尤其是服务端主动关闭连接后大量进入TIME_WAIT状态的情况。如果服务端和压测机器/客户端都在同一网段且不会经过NAT转换,可以开启TI
