本文目录导读:

- 应用线程与响应时间指标(Case 的“导火索”)
- JVM 内存与垃圾回收指标(Case 的“根源”)
- 数据库与中间件指标(Case 的“下游瓶颈”)
- 系统资源与 I/O 指标(Case 的“物理基础”)
- 如果你需要一套“优先排查顺序”,建议按此链路:
- 进阶补充(源码级案例):
在Java(尤其是服务端/后端)领域,“案例”通常指的是线上故障排查案例、性能调优案例或系统架构演进案例。
如果你是想知道在阅读或复盘这些案例时,哪些技术指标最值得重点关注,可以从用户端、应用端(JVM)、中间件/数据库端以及资源端四个维度来拆解,这些指标往往是定位问题的“第一现场”。
以下是Java案例中最值得重点关注的几类核心指标:
应用线程与响应时间指标(Case 的“导火索”)
绝大多数Java案例(如CPU飙升、接口超时)都是从这两个指标开始的。
- TP99 / TP999(高百分位延迟):比平均耗时(Avg)更真实。重点关注:如果TP999突然飙高,说明存在长尾请求,通常意味着存在锁竞争、GC停顿或外部依赖(数据库/第三方服务)变慢。
- 活跃线程数:重点关注 Tomcat/Jetty 的
Active Threads,如果线程数一直打满且处于WAITING(Blocking)状态,通常不是并发不够,而是线程阻塞(如访问数据库连接池耗尽、远程调用超时未断)导致线程“假死”。 - 线程池队列深度:如果是异步场景,队列堆积说明消费者处理速度远小于生产者速度,往往是下游瓶颈。
JVM 内存与垃圾回收指标(Case 的“根源”)
这是Java特有的重灾区,也是内存泄漏和长时间停顿的根源。
- GC 暂停时间:重点关注 Full GC(老年代回收)的频率和耗时,以及 Young GC 的暂停时间,Full GC 频繁(如几分钟一次或每秒多次),通常意味着老年代空间不足或内存泄漏。
- 堆内存压力(Used Heap):重点关注 GC 后的内存占用趋势,如果GC后内存无法回落(锯齿状图形持续上扬),大概率是存在对象泄漏(常见的如ThreadLocal、静态Map、未关闭的IO流)。
- Metaspace(元空间):在高频动态代理、反射或热部署场景下,容易产生
OutOfMemoryError: Metaspace,需要关注类加载数量。
数据库与中间件指标(Case 的“下游瓶颈”)
很多Java案例表面上是应用代码问题,实则是数据库或Redis拖垮了应用。
- 连接池使用率(活跃连接数):重点关注 数据库连接池(如 HikariCP/Druid)的
Active数是否逼近Maximum,一旦打满,所有后续请求都会在获取连接时阻塞,导致线程耗尽。 - 慢SQL 与数据库 CPU:如果应用耗时增加,重点关注 数据库端
QPS/CPU以及慢查询日志,最简单有效的调优案例,往往都是因为应用层发起了一条未走索引的全表扫描SQL。 - Redis/缓存命中率与阻塞:重点关注 缓存命中率下降(击穿/雪崩)以及Redis的
INFO commandstats中是否有KEYS *等阻塞命令。
系统资源与 I/O 指标(Case 的“物理基础”)
- CPU 使用率(用户态 vs 内核态):
- 用户态高:通常是真的在跑计算(如大循环、正则回溯、序列化)。
- 内核态高:重点关注 频繁的系统调用,如大量的小文件读写、网络包收发、Java NIO导致的上下文切换(
vmstat中的cs列高)。
- 磁盘 I/O 等待时间(
iowait):Java日志框架(特别是同步写盘)在多线程高并发下极易造成I/O阻塞,这是隐藏很深的问题。
如果你需要一套“优先排查顺序”,建议按此链路:
- 先看全局:CPU 和 内存(物理层面是否打满)。
- 再看应用:活跃线程数 和 TP99(是否阻塞)。
- 其次看GC:Full GC 频率(是否存在内存压力/泄漏)。
- 抓SQL:数据库连接池 和 慢SQL(外部依赖是否拖后腿)。
进阶补充(源码级案例):
如果深入到并发编程案例,建议重点关注:
- 锁的粒度(悲观锁 vs CAS 自旋锁的取舍)。
synchronized的膨胀升级(偏向锁->轻量级锁->重量级锁)。- 指令重排序与可见性(
volatile的语义失效场景)。
总结一句话: 在Java案例复盘时,线程状态 + GC表现 + 连接池水位 是三大核心中的核心,只要能快速拉出这三者的时间线数据,90%的案例都能定位到大致方向。