晚上十一点,告警群突然炸了。订单服务整条链路的P99响应时间从平时的200多毫秒直接飙到3秒以上,生产环境的CPU冲上90%多,数据库连接池被打满,后面排队请求一路顶到网关超时。更让人焦虑的是,第二天早上还有一场计划内的线上促销活动,系统已经处于随时可能雪崩的边缘。这个项目编号后面还挂了一串“20251231163201”的时间戳,就是我们内部建单的流水号,但那次调优,我估计自己短时间内忘不掉了。
前后折腾了大概三周,最终把核心下单接口的P99从2.3秒压回300毫秒以内,集群资源水位降了将近一半,顺手把整个微服务架构下的可观测性、压测流程和容量评估方法也重新捋了一遍。这篇文章就是这次实战的完整复盘。内容会覆盖排查思路、监控选型、调用链分析、数据库与缓存优化、JVM/线程池调优,以及压测和容量评估的方法。适合正在维护微服务系统、遇到过接口慢和资源告警的开发、运维、SRE同学参考。不管你是刚接手微服务项目,还是已经踩过不少坑,我相信这篇文章里的思路和方法都能给你一些启发。
1. 项目背景与调优的整体思路
1.1 问题是怎么暴露出来的
先说下项目背景。这是一个基于Spring Cloud技术栈搭建的电商类微服务系统,核心服务大概有十几个,包括网关、用户、商品、库存、订单、支付等,服务之间通过Feign进行HTTP通信,注册中心用的Nacos,配置中心用Apollo,缓存用的Redis Cluster,数据库是MySQL,分库分表后接了ShardingSphere。整体架构不算特别复杂,但在当时的流量下已经能感受到压力。
问题是在一次例行全链路压测中暴露的。压测脚本模拟用户从浏览商品、加购物车到提交订单的完整流程,结果发现下单接口的响应时间呈现明显的阶梯式增长。开始压测的前两分钟P99还能维持在500毫秒左右,但很快就开始飙升,等到并发线程数调到300的时候,P99直接破了2秒,错误率也在持续上升。紧接着生产环境也出现了类似症状,订单服务的CPU使用率居高不下,多次触发Hystrix熔断。
其实这类现象在微服务架构下非常典型。系统不是一下子挂掉的,而是某个节点先出现性能退化,然后通过调用链传导,最终拖垮整条链路。如果没有全局视角,你很容易陷入“头痛医头、脚痛医脚”的困境:看到CPU高就去加机器,看到数据库慢就加索引,但实际上问题的根因可能在更上游的服务。所以我在这次调优开始前,给自己定了一条规则:先度量,再定位,最后才优化。
1.2 调优前必须想明白的事
很多团队做性能调优,第一反应是“哪里慢改哪里”,这其实是最大的误区。微服务架构的性能问题具有明显的传导性和耦合性,一个服务的延迟上升,会通过线程池占用、连接池等待、队列堆积等方式扩散到其他服务。如果不对全局做度量,只盯着某个局部做优化,往往会出现按下葫芦浮起瓢的尴尬局面。
我在这次调优前,先问了三个问题:
- 哪些服务慢?是整个集群都慢,还是只有个别服务慢?
- 慢在哪个环节?是服务自身计算慢、数据库慢,还是远程调用慢?
- 容量到底够不够?当前集群的峰值承载能力是多少,离目标还有多远?
这三个问题对应的就是:监控指标、链路追踪、压测验证。在微服务架构下,这三件事必须全部做到位,性能调优才能变成一个可迭代、可验证的闭环,而不是靠直觉和猜测试碰运气。我之前在一些项目里见过,团队连基本的全链路监控都没有,出了问题只能一台台服务器上去看日志,效率极低。这次的实践经验告诉我,花上一周时间把可观测性建设好,后面调优节省的时间是三倍不止。
1.3 定调优目标:别再看平均响应时间
目标设定是个容易被忽视但极其关键的环节。很多团队习惯用平均响应时间(Avg RT)来评估系统性能,但平均值在性能调优中是个“骗人”的指标。举个例子:100个请求中,99个请求耗时100毫秒,只有1个请求耗时10秒,平均响应时间是199毫秒,看起来“还不错”,但真实体验是那一个慢请求就已经让用户抓狂了。
所以在这次调优中,我们用的是百分位指标,重点是P99和P95。P99的含义是99%的请求响应时间都小于等于这个值,它反映的是系统在最差情况下的表现,更能代表用户真实体验。我们定的目标也很明确:下单接口P99从2.3秒降到500毫秒以内,并尽量朝着300毫秒去优化;同时保证压测过程中错误率低于0.1%。有明确的目标,后面每一项优化措施是否有价值,都可以用它来检验。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 可观测性建设:没有数据,一切调优都是盲人摸象
2.1 链路追踪为什么是必需品
微服务架构下,一次用户请求往往要跨越多个服务节点。下单这个动作,前端调用网关,网关调用订单服务,订单服务要调库存服务验证库存,要调会员服务查询用户等级,还要写数据库、更新缓存。链路长、节点多,任
