1. 压测报告出来那一刻,我意识到事情没那么简单
先说背景。我负责的是电商核心链路里的订单服务,整个系统是标准的微服务架构:Nginx入口,网关做路由鉴权,下游拆了订单、库存、用户、支付、优惠券五个核心服务,服务之间走HTTP接口,数据库按业务域拆库,缓存统一走Redis。这套架构上线跑了快一年,平时流量不大,没出过什么大问题,直到那次618前的压测。
压测工具用的JMeter,线程数200,持续压了10分钟。结果报告一出来,整个人都有点懵:订单创建接口的QPS卡在800左右上不去,P99延迟却从平时的200ms一路飙到1.5秒,错误率在压测后半段开始抬头,逼近2%。更诡异的是,我看了所有Pod的监控,CPU使用率普遍在40%左右,内存也就用了50%不到,看着人人有余粮,但接口就是快不起来。这种"资源没打满、性能却上不来"的情况,在微服务架构里其实比CPU直接打满更让人头疼,因为它的根因往往藏在一整条调用链路的某个角落。
我当时的判断是:大概率不是某台机器扛不住了,而是链路里某个环节在排队、在阻塞,导致请求被卡住。这篇实战记录,就是我把整个调优过程从定位、分析到落地、验证完整跑一遍的复盘,包括链路追踪怎么用、线程池和连接池的参数到底怎么算、缓存策略怎么改才能扛住峰值、数据库层还能挤出多少性能,以及最后压测验证的真实数据对比。如果你也在做微服务架构的性能调优,或者在面试中被问到类似问题,这篇内容应该能给你一些可以直接落地的参考。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 先别急着加机器,用链路追踪把瓶颈钉死在某一层
很多人遇到性能瓶颈,第一反应是扩容、加Pod、加机器。这在无状态服务上确实有效,但如果瓶颈在下游的数据库、Redis或者第三方依赖上,加机器不仅没用,反而可能让情况更糟——更多实例意味着更多的数据库连接、更频繁的缓存访问,把已经紧张的资源进一步压垮。所以我的原则是:调优第一步永远是定位,而不是拍脑袋扩容。
2.1 为什么微服务链路里"看不到"的延迟最致命
微服务架构和单体应用最大的区别,就是一次用户请求会经过多个服务。订单创建这个接口,表面上是一个HTTP请求,实际上后端要走网关、订单服务、库存服务、用户服务、优惠券服务,再加上若干次Redis读写和数据库操作。任何一环慢了,整个链路就会被拖住。
单体应用里,方法调用是进程内的,延迟以毫秒计,出问题可以用Profiler直接看。微服务就不一样了,服务之间走网络,每一次远程调用都有网络开销、序列化开销、连接池获取开销,这些在单体应用里根本不存在的成本,在微服务里会被放大很多倍。而且最麻烦的是,你很难凭直觉判断延迟到底消耗在哪一层——可能是订单服务自身逻辑慢,可能是库存服务响应慢,也可能是网络抖动导致重试,甚至可能是某个服务的GC停顿导致的偶发超时。
这时候就需要链路追踪工具来把整条调用链路的耗时清晰地摊开来看。
2.2 Trace数据怎么读:瀑布图才是定位的第一现场
我们用SkyWalking做链路追踪,服务通过Agent方式接入,不用改业务代码。每个请求会分配一个全局Trace ID,从网关入口开始,经过的每一个服务、每一次远程调用、每一次数据库访问,都会作为一个Span被记录下来,最终在SkyWalking的界面上形成一张瀑布图。
教大家一个读瀑布图的技巧:不要看平均耗时,直接看P99的慢请求。把慢请求的Trace ID拎出来,点进去看它的Span列表,重点找两个东西——第一个是耗时最大的Span,第二个是耗时占比异常的跨度。正常情况下降序排列
