刚做后端的人常把这两件事混着说:面试里问「你怎么做高并发」,答「我开了多线程」,面试官不置可否;写代码时加了一堆线程池,线上照样排队。问题在于高并发描述的是系统的外部压力与结果,多线程只是内部实现手段之一,而且不是唯一手段。这篇帮你把两层分开,给出判断口径、对照表和一套可执行的排查顺序。
刚做后端的人常把这两件事混着说。面试里问「你怎么做高并发」,答「我开了多线程」,面试官不置可否;写代码时加了一堆线程池,线上照样排队。问题在于,高并发描述的是系统的外部压力和最终结果,多线程只是内部实现手段之一,而且远不是唯一手段。这篇帮你把这两层拆开,给出判断口径、对照表和一套能照着做的排查顺序。
读的时候可以带一个自己的问题进来:你手上那个接口,到底是「请求太多扛不住」,还是「一条请求处理得太慢」。这两个判断会导向完全不同的改法。分不清这两件事,后面所有的优化动作都容易打偏。
先把两层分开:一个是压力,一个是手段
高并发说的是「同一时间有多少请求在系统里」,这是外部视角、结果视角,衡量的是吞吐、延迟、错误率这些表现;多线程说的是「一个进程里开几条执行流」,这是实现视角。两者的关系是单向的:多线程可以用来应对高并发,但高并发不等于多线程,也不用非得多线程。异步 IO、协程、消息队列、加机器、加缓存,都是可选路径。
- 外部指标类:QPS、并发连接数、P95/P99 延迟、错误率——这些描述系统承受了什么压力、表现如何。
- 内部实现类:线程、协程、连接池、事件循环、线程池参数——这些描述程序怎么把活同时干起来。
- 一个常见的错位是:单机线程数上去了,但数据库连接池、下游接口、磁盘 IO 其中任何一环扛不住,整体表现还是上不去。
- 判断口径:先问「瓶颈在哪一环」,再问「这一环该用哪种并发模型」。顺序反了,就会变成为了用多线程而用多线程。
一张对照表:什么时候该想哪件事
| 你观察到的现象 | 更可能的问题方向 | 先动哪里 |
|---|---|---|
| 请求排队、响应变慢 | 某环节资源饱和 | 看 CPU、连接池、磁盘、下游的等待时间 |
| CPU 跑不满但吞吐上不去 | 卡在 IO 等待 | 别急着加线程,先看阻塞点在哪 |
| 单条请求本身就慢 | 处理逻辑或下游慢 | 先优化那一环,跟并发模型关系不大 |
| 并发上来后数据错乱 | 共享状态竞争 | 查锁粒度、幂等和写入顺序 |
多线程适合任务本身是 CPU 密集、或者需要用到阻塞式库又不想改造成本太高的场景。但线程数要按「CPU 核数 × 系数」起步再实测调整,不是越大越好。高并发场景更常见的组合是:连接层用异步或事件驱动扛住连接数,业务层用有限线程池控制对下游的冲击,再加缓存、队列削峰、限流兜底。
不适用的情形也要说清楚:如果请求量本来就不大,或者瓶颈明确在单条 SQL、单个下游接口上,引入复杂并发模型只会让排错更难。这时候先把慢的那一环修掉,收益比换并发模型大得多。
上手前的判断清单与排查顺序
- 先定指标写清楚目标 QPS、可接受的 P95/P99 延迟、错误率上限。没有这三个数,高并发就是一句空话,也没法判断优化有没有生效。
- 量出基线用测速类工具先量单机基线,看清楚是延迟型瓶颈还是吞吐型瓶颈。到 /tools/speed-test 记录你自己的延迟基线,别拿别人的数字当参考。
- 按顺序排查入口连接数 → 应用线程或协程配置 → 连接池大小 → 下游接口与数据库 → 缓存命中 → 有没有限流和降级。哪一环等待时间最长,先修那一环。
- 最后才加并发每加一档都复测一次,记下线程数、连接池、QPS、延迟四个值的对应关系。加完不复测,等于没调。
- 对齐口径并发数和限流阈值不是一回事,别用同一个数字糊弄过去。相关术语可以到 /ai-dict/category/infra 先把口径对齐。
这套顺序的重点是「先测量、再判断、最后才动并发参数」。很多人的做法正好反过来,先加线程池,再看现象,结果改了半天也不知道是哪一步起了作用。
初学者最容易踩的几个坑
- 把「线程开得多」当成「并发能力强」。线程越多,上下文切换和锁竞争越重,超过拐点之后吞吐反而下降。
- 忽略了共享状态。多线程一旦碰到同一份数据,就要考虑锁粒度、幂等和顺序问题;很多线上诡异问题不是并发不够,而是并发上去之后数据写坏了。
- 用本地内存做计数或缓存,多实例部署后直接对不上。这类问题在单机测试时完全看不出来。
- 以为换个语言或框架就自动解决。语言只改变写并发的成本,不改变系统的瓶颈位置。
还有一个容易被忽略的点:高并发的兜底手段(限流、降级、排队)往往比并发模型本身更能决定系统在压力下的表现。压力来的时候,能优雅地拒绝一部分请求,比硬扛到全挂要好。这些东西的判断门槛,可以到 /tools/speed-test 连同你自己的基线一起看,先知道自己系统的天花板在哪,再决定要不要往上加压。
下一步把自己项目的入口连接、线程或协程配置、连接池大小、下游接口耗时各记一行,按上面的排查顺序走一遍,再回头判断到底该动哪一层。相关的实测基线和工具可以到站内测速与工具目录核对当时的数字。→常见问题
多线程是不是实现高并发的必要条件?
不是。高并发关心的是系统整体能同时处理多少请求,异步 IO、协程、消息队列、水平扩容都能达到目的。多线程只是其中一种手段,而且它在 IO 等待型场景里性价比通常不高,因为线程大部分时间在等,却占着内存和调度开销。
我接口压测 QPS 上不去,是不是该加线程数?
先别加。按这个顺序查:CPU 利用率高不高、有没有大量线程处于等待状态、数据库和下游接口的响应时间是多少、连接池有没有被打满。如果是某条 SQL 或某个下游慢,加线程只会让它们被压得更死,问题会更明显而不是更小。
小团队要不要一上来就按高并发设计?
不需要,但要留出改的余地。按当前真实流量的两三倍做容量规划就够了,重点是让瓶颈可观测、让扩容和降级有明确开关。真正的高并发设计是一轮轮压测和排查攒出来的,不是一开始画架构图能画出来的。