← 返回全栈资料库
📊 生产数据概念
QPS / TPS / RT / 并发量 / 带宽 / 数据量 —— 这些数字到底多大才算正常?面试问你系统多大规模,你需要有概念
QPS / TPS(每秒处理多少请求)
什么是 QPS / TPS
QPS(Queries Per Second)= 每秒处理多少个请求。
TPS(Transactions Per Second)= 每秒处理多少个事务(一个事务可能包含多个请求)。
面试一般问 QPS。回答时用 QPS 即可。
不同业务规模的 QPS 参考
| 系统类型 | 日常 QPS | 峰值 QPS | 什么概念 |
| 个人博客/官网 | 10~50 | 200 | 一秒钟十几个人在看,小网站 |
| 企业内部系统 | 50~200 | 500 | 公司几百人用的 OA/CRM/审批系统 |
| 中型电商/APP | 500~2000 | 5000 | 日活几十万的APP,有用户在浏览下单 |
| 大型电商(京东/淘宝级) | 5000~20000 | 10万+ | 双11秒杀级别,万级并发 |
| 国民级应用(微信/抖音) | 10万+ | 百万级 | 亿级日活,超高并发 |
一台服务器能扛多少 QPS
| 场景 | 单机QPS参考 | 瓶颈在哪 |
| 纯静态接口(Nginx直接返回) | 5万~10万 | 网卡带宽 |
| 简单查询(Redis 直接返回) | 5万~10万 | Redis 单线程瓶颈 |
| 读DB(有索引,单表查询) | 1000~3000 | DB 连接数 / 索引效率 |
| 写DB(INSERT/UPDATE) | 500~1500 | DB 锁 / IO |
| 复杂业务(调多个服务+DB+Redis) | 200~800 | 下游依赖RT累加 |
| 秒杀场景(极端写压力) | 100~500 | DB 写锁 + 库存竞争 |
面试怎么说:「我们的合规系统日常 QPS 约 200~500,大促时峰值 2000 左右。用 4 台 4C8G 的机器扛,单机 QPS 约 500。瓶颈在 MySQL 查询,加了 Redis 缓存后 DB 压力降了 70%。」
RT / 响应时间(接口要多快)
用户能接受的响应时间
| RT 范围 | 用户感受 | 常见场景 |
| < 100ms | 极快,感觉不到延迟 | Redis 查询、静态资源 |
| 100~300ms | 流畅 | 有索引的 DB 查询、缓存命中 |
| 300~500ms | 正常,可接受 | 复杂业务(多表JOIN+聚合) |
| 500ms~1s | 有点慢,用户会注意 | 报表导出、大数据量查询 |
| 1~3s | 慢,用户会不耐烦 | 需要优化了 |
| > 3s | 超时,用户离开 | 严重问题,必须修 |
P50 / P95 / P99 是什么意思
面试说接口 RT 不能只说平均值,要说分位值:
P50(中位数)= 50% 的请求在这个时间内完成。
P95 = 95% 的请求在这个时间内完成(有 5% 比这慢)。
P99 = 99% 的请求在这个时间内完成(有 1% 比这慢,这些是长尾请求)。
为什么要看 P99:平均值会被大量快请求拉低。比如 99 个请求 50ms + 1 个请求 5s,平均才 100ms 看起来不错,但那 1 个用户等了 5 秒。P99 会暴露这个长尾问题。
| 指标 | 参考值 | 含义 |
| P50 | < 100ms | 大部分用户体验流畅 |
| P95 | < 300ms | 95% 用户正常 |
| P99 | < 500ms | 99% 用户正常(1% 长尾可容忍) |
| 超时阈值 | 3s | 超过 3s 直接超时返回失败 |
面试怎么说:「我们接口 P50 大约 80ms,P95 约 200ms,P99 偶尔到 500ms。P99 长尾主要是偶尔有慢SQL,加了索引和 Redis 缓存后好了很多。」
并发量(同时在处理的请求数)
QPS 和并发量的关系
并发量 = QPS × RT(秒)
举例:QPS = 1000,RT = 0.2s → 并发量 = 1000 × 0.2 = 200
意思是:同一时刻有 200 个请求正在被处理。
反推:如果你的服务器并发能力是 200,RT = 0.2s → 能扛 QPS = 200 / 0.2 = 1000。
不同层级的并发能力参考
| 组件 | 能扛并发 | 怎么提升 |
| Nginx | 5万~10万 | worker_processes + worker_connections |
| Redis | 10万 QPS | 单线程,靠纯内存+IO多路复用 |
| MySQL | 1000~5000 QPS(读写分离后更高) | 连接池 / 索引 / 读写分离 |
| Tomcat | 默认200线程 → 约200~1000并发 | server.tomcat.threads.max=500 |
| Java 应用 | 取决于线程池+DB连接池+下游RT | 线程池调优 / 异步化 |
关键认知:并发能力不是无限提升的。线程太多 → CPU 上下文切换开销大 → 反而更慢。找到最优线程数(CPU密集型=N+1,IO密集型=2N~10N)比盲目加大更重要。
容量估算(系统设计面试必考)
面试官问"你的系统多大规模",你怎么算
从用户量推 QPS 的公式:
| 步骤 | 公式 | 举例(日活100万的APP) |
| 日活用户 | 已知 | 100万 |
| 每日请求总量 | 日活 × 每人每天请求次数 | 100万 × 50 = 5000万次/天 |
| 日均QPS | 每日请求 / 86400秒 | 5000万 / 86400 ≈ 580 QPS |
| 峰值QPS | 日均QPS × 3~10倍(看业务,秒杀可能100倍) | 580 × 5 ≈ 2900 QPS |
| 需要多少台机器 | 峰值QPS / 单机QPS | 2900 / 500 ≈ 6台(加2台冗余 = 8台) |
存储量估算
| 数据类型 | 单条大小 | 每日增量 | 一年存储 |
| 用户数据 | 1KB | 新增1万用户 = 10MB | 3.6GB |
| 订单数据 | 2KB | 10万订单 = 200MB | 72GB |
| 操作日志 | 500B | 1000万条 = 5GB | 1.8TB → 考虑冷热分离 |
| 图片(头像/商品图) | 200KB | 1万张 = 2GB | 730GB → 上OSS |
带宽(网络要多大)
带宽和数据量的换算
| 带宽 | 实际速度 | 什么概念 |
| 1 Mbps | 128 KB/s | 下载一个 1MB 图片要 8 秒 |
| 10 Mbps | 1.25 MB/s | 小网站最低配置 |
| 100 Mbps | 12.5 MB/s | 中型应用标准配置 |
| 1 Gbps(千兆) | 125 MB/s | 大型应用 / 内网服务器 |
| 10 Gbps(万兆) | 1250 MB/s | 数据中心内网互联 |
注意单位:带宽说 Mbps(兆比特),下载速度说 MB/s(兆字节)。1 Byte = 8 bit → 100M带宽的实际下载速度约 12.5MB/s(除以8)。
带宽够不够怎么算
QPS = 1000,每个请求返回数据 10KB →
每秒传输 = 1000 × 10KB = 10MB/s → 需要 100Mbps 带宽(10MB × 8 = 80Mbps)
图片/视频是带宽杀手。一张高清图 500KB,100人同时看 → 50MB/s → 需要 500Mbps 带宽。所以图片走CDN,不占服务器带宽。
数据库相关数据
MySQL 性能参考值
| 指标 | 参考值 | 说明 |
| 单表行数 | 建议<2000万 | 超过后B+树索引变高,查询变慢 |
| 单表存储 | 建议<10GB | 超过考虑分表 |
| 连接池大小 | 20~200 | HikariCP 默认10,生产建议50~100 |
| 慢查询阈值 | >1秒 | 超过1秒就该优化(加索引/改SQL) |
| 单机QPS(读) | 3000~5000 | 有索引的简单查询 |
| 单机QPS(写) | 500~1500 | INSERT/UPDATE,受锁影响 |
| 读写分离后QPS | 1万~3万 | 1主3从,读分到从库 |
Redis 性能参考值
| 指标 | 参考值 | 说明 |
| 单机QPS | 8万~10万 | 单线程,纯内存,IO多路复用 |
| 单Key大小 | 建议<10KB | 太大阻塞其他操作 |
| 单实例内存 | 建议<10GB | 太大 → RDB/AOF 持久化慢 → fork 卡 |
| 缓存命中率 | >95% | 低于95%说明缓存设计有问题 |
| 过期时间 | 加随机抖动 | 同时过期 → 缓存雪崩 |
JVM 相关数据
| 指标 | 参考值 | 说明 |
| 堆内存(4C8G机器) | Xmx=4G~5G | 留2~3G给OS+堆外+元空间 |
| 堆内存(8C16G机器) | Xmx=8G~12G | 超过12G GC停顿明显 |
| Young GC 频率 | 每秒几次~几十次正常 | YGC 很快(几ms),频繁也没事 |
| Full GC 频率 | 不应该频繁出现 | 几小时一次还行,几分钟一次就有问题 |
| Full GC 停顿 | <200ms(G1) | 超过500ms用户能感知到卡 |
| 线程数 | 200~500 | 超过1000要排查是否有线程泄漏 |
| 线程池大小 | CPU密集=N+1 / IO密集=2N | N=CPU核数 |
一张表记住所有关键数字
| 指标 | 记住这个数 | 一句话 |
| Redis QPS | 10万 | 单机Redis能扛10万QPS |
| MySQL QPS | 3000读/1000写 | 读写分离后能到1万+ |
| MySQL单表 | 2000万行/10GB | 超过考虑分表 |
| Java单机QPS | 500~1000 | 复杂业务,简单查询更高 |
| 接口RT | P99<500ms | 超过1s就该优化 |
| 峰值QPS | 日均×5~10 | 秒杀场景×100 |
| 堆内存 | 机器内存的60~70% | 留余量给OS |
| Full GC | 几小时一次 | 几分钟一次=有问题 |
| 缓存命中率 | >95% | 低于说明缓存设计有问题 |
| 连接池 | 50~100 | HikariCP默认10太小 |
面试怎么说:「我们的合规系统日活约5万,日常QPS约300,峰值约1500。4台4C8G应用机器 + 1主2从MySQL + 3节点Redis集群。接口P50约80ms、P99约300ms。缓存命中率97%。MySQL单表最大约800万行,还没到分表的程度。」
不用编造,但要对数字有概念。面试官问"你的系统能扛多少QPS",你能答出量级(几百/几千/几万)就够了。
压测(压力测试)
什么时候需要压测
| 场景 | 为什么要压 | 什么时候做 |
| 大促/秒杀前 | 预估能不能扛住峰值流量 | 活动前1~2周 |
| 新系统上线前 | 验证系统在预期负载下的表现 | 上线前 |
| 性能优化后验证 | 加了缓存/改了SQL,效果到底多少 | 优化完立即压 |
| 扩容评估 | 需要多少台机器才能扛目标QPS | 容量规划时 |
| 定位瓶颈 | 系统先撑不住的是CPU/内存/DB/带宽哪个 | 发现问题但不知道卡哪 |
压测压什么(4种类型)
| 类型 | 怎么压 | 验证什么 | 参考指标 |
| 基准测试 | 单接口,低并发(1~10),跑稳定后看RT | 这个接口的"底子"有多快 | RT应该是最快的(几ms~几十ms) |
| 负载测试 | 逐步加并发(10→100→500→1000),看什么时候开始变慢 | 找到系统的拐点(QPS到多少开始RT飙升) | RT从50ms涨到200ms的那个点 |
| 压力测试 | 直接打超过预期的并发,看系统什么时候崩 | 系统的极限在哪、崩了怎么恢复 | 错误率从0%变成1%的那个点 |
| 稳定性测试 | 中等并发长时间跑(几小时~几天) | 有没有内存泄漏、连接泄漏、性能衰减 | RT和内存应该稳定不涨 |
压测工具
| 工具 | 适合场景 | 难度 |
| JMeter | 最通用,HTTP/数据库/MQ都能压,有GUI | 中(需要写测试计划) |
| Wrk / Ab | 命令行快速压一个HTTP接口 | 低(一行命令搞定) |
| Gatling | 代码写压测脚本,报告漂亮,适合CI集成 | 高(要写Scala/Java) |
| 全链路压测 | 阿里造的概念,模拟真实用户从入口到DB的全链路 | 极高(需要影子库+流量录制) |
# wrk 快速压测示例:100并发,持续30秒
wrk -t4 -c100 -d30s http://localhost:8080/api/orders?page=1&size=20
# 输出示例:
# Requests/sec: 1247.53 ← QPS约1247
# Latency: 78.32ms ← 平均RT 78ms
# 50%: 65ms
# 90%: 120ms
# 99%: 340ms ← P99 340ms
# Non-2xx or 3xx responses: 0 ← 错误率0%
压测结果怎么看(面试常问"你怎么判断系统扛得住")
| 指标 | 怎么看 | 达标标准 |
| QPS | 压测工具输出的 Requests/sec | ≥ 预估峰值QPS的1.5倍(留余量) |
| RT(P99) | 压测工具输出的延迟分位 | P99 < 500ms(或业务要求值) |
| 错误率 | 非2xx响应占比 | 0%(出现错误说明到极限了) |
| CPU使用率 | 压测时看监控(top / Grafana) | < 70%(超过说明到瓶颈了) |
| 内存 | 压测时看 Heap 曲线 | 稳定不持续涨(涨=泄漏) |
| DB连接数 | 看 MySQL SHOW PROCESSLIST 或监控 | < 连接池最大值的80% |
| DB慢查询 | 压测时看慢查询日志 | 不应该大量出现(有就优化) |
面试怎么说:「大促前我们做了全链路压测,目标QPS 3000。结果在2000 QPS时MySQL CPU到85%、P99到600ms。定位到是订单查询没走索引,加了联合索引+Redis缓存后,3000 QPS下P99降到200ms,MySQL CPU降到60%。最终留了50%余量上线。」
数据库性能拐点(多少数据开始变慢)
MySQL 单表性能拐点
| 数据量 | 性能表现 | 要做什么 |
| < 100万行 | 正常,有索引查询<10ms | 不用管 |
| 100~500万行 | 基本正常,偶尔慢查询 | 检查索引是否合理,优化慢SQL |
| 500~2000万行 | 复杂查询开始变慢,大表DDL卡 | 归档历史数据 / 加缓存 / 预估是否要分表 |
| 2000~5000万行 | 明显变慢,索引也可能慢,DDL几个小时 | 考虑分表(按时间/用户ID拆) |
| > 5000万行 | 几乎所有操作都慢,运维痛苦 | 必须分库分表 |
为什么是2000万?B+树索引3层能存约2000万行(每页16KB,非叶子节点存指针,叶子存数据)。超过2000万后B+树变成4层,多一次磁盘IO,查询明显变慢。2000万不是绝对值(行宽大的表可能500万就慢),但作为经验参考。
什么操作会让数据库变慢
| 操作 | 为什么慢 | 什么时候触发 | 怎么解决 |
| 没索引的查询 | 全表扫描,逐行比对 | WHERE条件字段没建索引 | 加索引 |
| 大分页(LIMIT 100万,10) | 要扫描前100万行再丢弃 | 列表页翻到很后面 | 游标分页(WHERE id > last_id) |
| SELECT * | 读取不需要的列+无法用覆盖索引 | 图省事写SELECT * | 只查需要的列 |
| N+1查询 | 循环里每次查一次DB | 遍历列表时关联查详情 | JOIN / 批量IN查询 |
| 大表DDL(ALTER TABLE) | 要锁表重建,几百万行卡几分钟 | 加字段/改字段类型 | 用pt-online-schema-change(不锁表) |
| 大事务 | 持锁时间长,阻塞其他事务 | 批量更新没有分批 | 拆小事务(每批1000条) |
| LIKE '%关键词%' | 左模糊无法走索引 | 搜索功能 | 用ES做全文搜索 |
| ORDER BY + LIMIT大偏移 | 要排序大量数据再取几条 | 排行榜/最新列表 | 用Redis ZSet做排行榜 |
怎么判断数据库该优化了
| 信号 | 说明 | 参考阈值 |
| 慢查询数突然增多 | 慢查询日志里 >1秒的SQL数量上涨 | 每天 >100条慢查询就该查 |
| DB CPU 持续偏高 | Grafana看MySQL CPU曲线 | 持续 >70%不回落 |
| 连接池经常打满 | 应用报"Could not get JDBC Connection" | 活跃连接数 = 连接池最大值 |
| 接口RT和DB有关联变慢 | APM链路追踪里DB段耗时占比大 | DB段 > 总RT的50% |
| InnoDB行锁等待 | SHOW ENGINE INNODB STATUS 有大量锁等待 | lock_wait >0 且频繁 |
| 磁盘IO打满 | iostat看 %util | %util持续 >80% |
生产观测指标(面试官爱问"你怎么知道系统健不健康")
日常巡检看什么(每天扫一眼)
| 指标 | 正常值 | 告警值 | 说明 |
| QPS | 日常波动范围内 | 突然飙升3倍或跌到0 | 飙升=被刷/被攻击/bug,跌到0=挂了 |
| 错误率 | <0.1% | >1% | 突然升高=有bug或下游挂了 |
| P99 RT | <300ms | >1s | 变慢=GC/DB/下游慢 |
| CPU使用率 | 30~60% | >80%持续5分钟 | 高=流量大/GC/死循环 |
| 内存使用率 | 40~70% | >85% | 高=泄漏/OOM前兆 |
| Full GC | 几小时一次 | 1分钟内 >3次 | 频繁=内存不够/泄漏 |
| DB连接数 | <连接池80% | = 连接池最大值 | 打满=慢SQL/大事务/连接泄漏 |
| Redis内存 | <maxmemory 80% | >90% | 高=需要扩容或清理 |
| Redis命中率 | >95% | <90% | 掉=缓存设计有问题/key过期了 |
| 磁盘使用率 | <70% | >85% | 高=日志/数据需要清理 |
| MQ积压量 | 接近0(消费跟上) | >1万条持续不降 | 积压=消费者挂了/处理太慢 |
连通性测试(接口探活)
除了业务指标,还要监控基础设施是否通:
| 检测项 | 怎么检测 | 多久检测一次 |
| HTTP接口探活 | GET /health 返回200 | 每10~30秒 |
| DB连通性 | SELECT 1(最简单的SQL能跑通) | 每30秒 |
| Redis连通性 | PING → PONG | 每30秒 |
| 下游服务连通性 | 调下游的/health接口 | 每30秒 |
| 外部API连通性 | 调第三方/health或ping | 每1分钟 |
| 证书是否过期 | 检查HTTPS证书到期时间 | 每天 |
面试怎么说:「我们用 Prometheus+Grafana 看日常指标,关键指标(QPS/错误率/P99/CPU/DB连接数)配了钉钉告警。健康检查接口 /health 检测 DB+Redis+下游连通性,K8s 每10秒探活,失败3次自动重启Pod。」
全链路测试
什么是全链路测试
不是只压一个接口,而是模拟真实用户从入口到最终结果的完整路径。比如电商:浏览商品 → 加购物车 → 下单 → 支付 → 查看订单。每一步都走通才算成功。
| 测试类型 | 验证什么 | 什么时候做 |
| 全链路功能测试 | 用户从入口到完成操作,每一步都能走通 | 每次发版前 |
| 全链路压测 | 高并发下整条链路是否扛得住(哪个环节先撑不住) | 大促前 |
| 全链路回归 | 改了A模块,B/C/D模块不受影响 | 发版前 |
| 故障注入(混沌工程) | 故意杀掉一个服务/DB,看链路是否能降级不死 | 稳定性演练 |
全链路压测的难点
| 难点 | 说明 | 怎么解决 |
| 压测数据不能污染生产 | 压测产生的订单不能混进真实订单 | 压测数据打标(标记压测请求)+ 影子库/影子表 |
| 第三方接口不能真调 | 不能真的调支付/短信 | Mock 或挡板(返回假数据) |
| 链路太长不好编排 | 10个服务的调用链,手动编排很痛苦 | 录制真实流量回放(流量录制+回放) |
| 瓶颈定位难 | 慢了不知道卡在哪个服务 | 全链路APM(SkyWalking traceId串联) |
生产数据概念 · QPS/RT/并发/容量/带宽/压测/DB拐点/观测指标 · 全栈资料库