从车机配置查询案例学会做容量评估
关键词:容量评估、QPS、并发度、CPU 净时间、线程模型、内存占用、RT、RTT、POC
一、写在前面
上周老板问:"50 万台车每天启动时来拉配置,云侧到底要几台机器?" 本文把复盘过程整理成两套可复制的口袋模型:
- 业务 QPS 评估模型(峰值怎么来)
- 资源评估模型(单机能扛多少、要几台)
所有推导都在 50 万车机真实场景跑通,换任何业务直接套公式即可。
二、基础概念速查(必背)
| 概念 | 符号 | 单位 | 一句话解释 | 备注 |
|---|---|---|---|---|
| QPS | Q | req/s | 每秒钟完成的请求数 | 同 TPS、RPS QPS = Concurrency / 平均响应时间(单位:秒) |
| 并发度 | C | 条 | 同一时刻正在处理的请求数 | Tomcat 活跃线程数 |
| 响应时间 | RT | ms | 单请求端到端耗时 | 含网络+计算 |
| CPU 净时间 | cpu | ms | 请求真正占满 CPU 核心的时间 | 不含 IO wait |
| CPU 利用率 | η | % | 业务代码吃掉的总 CPU 占比 | 留 20~40% 余量 |
| 最佳线程数 | — | 条 | 把 CPU 跑满又不上下文爆炸的线程数 | IO-bound≈核×3~4 |
| RTT | — | ms | 一次网络往返耗时 | 同机房 0.3 |
| 集中系数 | β | % | 流量在"最尖"窗口的占比 | 上下班 30%,秒杀 50%+ |
三、快速计算公式
-
业务量模型,算出峰值QPS
峰值QPS = N × α × β / tt = 600 s(10 min 集中窗口)
→ 500 000 × 0.8 × 0.3 / 600 ≈ 200 QPS -
**计算单节点QPS **
QPS = Concurrency / 平均响应时间并发度 = CPU核数*3~4
平均响应时间,单位秒
-
计算资源节点数
n = 峰值QPS / 单节点QPS
四、详细计算过程
(一)业务 QPS 评估模型(3 步出峰值)
1. 业务量模型
| 参数 | 符号 | 分析 | 数值 |
|---|---|---|---|
| 总设备数 | N | 车辆总数:50万辆 | 50万 |
| 日活跃比例 | α | 启动规律 工作日早高峰 07:00-09:00(120 min) 工作日晚高峰 17:00-19:00(120 min) 假设 80% 的车在高峰时段内各启动 1 次 → 50w × 0.8 = 40w 次 / 高峰 | 80% |
| 高峰时段 | T | 2 h | 2 h |
| 高峰集中系数 | β | 按“30% 的车集中在 10 min 内启动”计算最严苛场景 | 30% |
| 高峰集中时间 | t | 按“30% 的车集中在 10 min 内启动”计算最严苛场景 | 10 min |
2. 峰值 QPS 公式
峰值QPS = N × α × β / t
t = 600 s(10 min 集中窗口)
→ 500 000 × 0.8 × 0.3 / 600 ≈ 200 QPS
3. 均值 QPS
日均QPS = 日请求量 / 86400
40 万 × 2 次 / 86400 ≈ 9.3 QPS
结论:日常<10 QPS,早/晚高峰 20× 突刺到 200 QPS,扩容策略按峰值即可。
(二)、资源评估模型(单机能力)
分析过程:
下面把“并发度”到底怎么算、为什么要结合单次请求 CPU 消耗一起考虑,用 2C4G 这个实例彻底拆开讲一遍。看完你就能自己套用到任何机型/任何业务。
一、先分清三个概念
-
并发度(Concurrency)
同一时刻正在处理的请求个数。Tomcat 里就是“活跃的 Worker 线程”数量。 -
QPS(Throughput)
每秒钟能完成的请求数。 -
CPU 时间(CPU time)
请求在整个生命周期中真正占满 CPU 核心的净耗时(不含网络等待、sleep、锁阻塞)。
二、一条公式
QPS = Concurrency / 平均响应时间
想提高 QPS,要么
① 提高并发度(多加线程/协程),要么
② 降低响应时间(优化代码、加缓存)。
但并发度不能无限加,它受两个硬天花板限制:
A. CPU 天花板
单核 1 s 只能给出 1000 ms 的 CPU 时间;
2 核就是 2000 ms/s。
B. 内存天花板
每条请求存活期间要占堆内存;堆满了就 Full GC/OOM。
三、把“CPU 净时间”换算成“并发上限”
- 已知单次请求 CPU 净耗时 21 ms(根据业务处理过程拆解)。
- 2 核实例,安全 CPU 利用率 60% → 每秒钟可提供 2000 ms × 0.6 = 1200 ms 的 CPU 时间。
- 因此,每秒最多同时“跑”
1200 ms ÷ 21 ms ≈ 57 份 CPU 片段。
换句话说:并发度 ≤ 57 时,CPU 不会飙过 60%。
四、把“内存占用的并发上限”也算出来
- 单请求存活期平均占 20 MB(堆+栈+DirectBuffer)。
- JVM 最大堆 3 GB,留给请求 2 GB(系统+缓存占 1 GB)。
- 2 GB ÷ 20 MB ≈ 100 并发。
内存天花板 > CPU 天花板,因此CPU 先撞墙。
五、线程不是越多越好
- 2 核下开 200 条 Worker 线程,操作系统会频繁切换上下文,反而降低有效 CPU 时间;
- 实测/经验公式:CPU 核心数 × 3~4 是 CPU-bound 场景的最佳线程数;
- 我们的场景里 60% 时间线程在等网络,属于 IO-bound,可以略多,但 8 线程已能把 2 核跑满。
六、综合取最小值
| 限制维度 | 上限并发度 |
|---|---|
| CPU 安全 | 57 |
| 内存 | 100 |
| 线程调度最优 | 8~10 |
生产环境按最保守的“线程调度”取 8 线程,再留 25% 余量 → 5~6 并发即可。
1. 四大限制维度
| 维度 | 计算式 | 本案例结果 |
|---|---|---|
| CPU | 每秒可提供的CPU时间:cpu_time_per_sec = 核数×1000ms×利用率 | 2 核 60% → 1200 ms/s |
| 内存 | 内存并发上限:mem_available / mem_per_req | 3 GB / 20 MB = 150 并发 |
| 线程调度 | 推荐的线程数量:core×k(IO-bound k=3~4) | 2×4=8 线程最优 |
| IO 等待 | 已折算进响应时间 | 81 ms(含 60 ms 网络) |
2. 单节点 QPS 推导
-
先找真瓶颈
CPU 并发上限 = 1200 ms / 21 ms ≈ 57(理论)
线程最优 = 8(实测)
→ 取小值 8,留 25% 余量 并发度 = 5 -
再算吞吐
QPS = Concurrency / 平均响应时间 = 5 / 0.081 s ≈ 62 QPS -
极限峰值
8 / 0.081 ≈ 99 QPS(CPU 打到 100%,只给突发用)
3. 机器数
min_nodes = 峰值QPS / 单节点安全QPS
= 200 / 62 ≈ 3.2 → 4 节点
加 N+1 冗余、双可用区 → 6~8 节点即可。
五、常见坑提醒
-
把 RT 当 CPU 时间
81 ms 响应里只有 21 ms 占 CPU,别直接用 81 ms 去算 CPU 上限! -
线程数无脑 200
2 核跑 200 线程,上下文切换能把 CPU 30% 吃光,吞吐量反而下降。 -
忽略内存泄漏
评估时按峰值常驻*1.5 倍留堆空间,防止 Full GC 把并发度打对折。 -
远程 DB/Redis 遗漏 RTT
若改为远程查询,把额外 3~5 ms 加进响应时间,再重算一遍即可。