服务性能瓶颈思考
流量指标
系统日活
系统支持最大qps
节点cpu使用率
内存占用率
接口平均响应时间
接口错误率
机器配置
性能瓶颈分析
1.代理层
出现问题:响应大量502、504
造成原因:连接数超过最大限制
解决方案: 代理层做限流,熔断
2.应用层
出现问题:接口响应慢甚至超时;cpu打满,内存打满;系统响应慢甚至卡死,系统重启;
造成原因:
web容器线程池打满导致后续请求被拒绝;
多个线程大量执行cpu密集型任务将cpu打满;
大量请求导致生成大量临时对象,如果内存不足将会频繁触发gc,系统卡顿,cpu打满;
大量请求如果长时间占用大量对象无法释放,导致oom,系统重启;
解决方案:
水平扩容,多节点部署,负载均衡避免单节点流量压力;
垂直扩容,单个节点加配置,cpu核心数,内存大小。jvm参数调优,减少gc压力;
请求限流+熔断,避免超预估请求量直接打到节点上。nginx/网关做请求流量限制和用户/ip限制,耗时接口做接口级限制;
合理减少线程数量,避免频繁上下文切换导致cpu卡死;
非核心逻辑利用MQ异步化处理;
3.数据库层
出现问题:数据库响应慢
造成原因:如果大量请求做慢查询,将数据库整体性能下降
解决方案:
慢sql优化,提高索引命中率,尽量使用覆盖索引,尽量减少关联查询;
引入缓存层,提高查询效率;
分库分表,读写分离,主从同步,多个从库负责查询;
复杂查询,慢查询做限流处理;
(如果数据库连接数做了限制,能防止数据库因连接数爆炸而直接崩溃,也能限制并发查询数量,避免超高并发瞬间压垮数据库)
4.缓存层
出现问题:缓存雪崩,缓存击穿
造成原因:大量key同时过期或者redis挂了,导致大量请求直接请求db;热点key突然过期失效,导致大量请求直接请求db,然后并行重新set缓存;
解决方案:redis高可用部署;分散redis过期时间;热点key永不过期 改为主动刷新;并行构建缓存加分布式锁;
5.消息中间件层
出现问题:消息积压
造成原因:生产者生产大量消息,消费者消费能力不足*(单线程,逻辑慢,非批量)
解决方案:消费者扩容多节点,多线程消费,提升消费能力;限流,短时间限制生产者消息; 消费者逻辑优化,攒够1000条批量处理,而非逐条处理;RocketMQ批量消费的功能 参数(消息条数,消息体大小,超时时间)
调优策略
-
先限流,后扩容:限流是第一道防线,扩容是兜底手段。
-
全链路压测:真实模拟高并发,找到真实瓶颈点(往往在数据库或缓存)。
-
监控告警:对线程池、GC、连接池、MQ Lag等关键指标设置告警。
一套支持2000QPS的配置方案
四个无状态节点,4核8g
单节点数据库连接池连接数: 20 (数据库连接数 ≈ CPU 核心数 * 2 + 磁盘数) (mysql最大连接数默认151)
单节点tomcat线程池最大线程数量: 200

浙公网安备 33010602011771号