线上问题定位与排查实战:从日志到优化的完整思路

遇到线上问题,第一要务永远不是盲目重启、不是猜原因、不是急着改代码,而是查看日志,定位报错信息

日志是线上问题的 "黑匣子",包含了问题发生的时间、调用链路、异常堆栈、关键入参出参、数据库执行语句等关键信息。脱离日志的排查基本都是 "盲猜",效率极低且容易误判。

1.1 日志查看的常规路径

  • 应用日志:业务异常、NPE、SQL 错误、第三方调用失败
  • 网关 /nginx 日志:请求流量、4xx/5xx 状态码、超时记录
  • 数据库日志:慢查询、死锁、连接数耗尽、执行失败
  • 系统日志:OOM、文件句柄不足、网络异常

1.2 日志排查步骤

  1. 确定问题发生时间范围,缩小日志检索区间
  2. 根据报错接口 / 服务名,过滤对应日志
  3. 定位异常堆栈,找到抛出异常的代码行
  4. 结合入参、调用链路,复现问题场景
  5. 判断是代码 Bug、配置错误、依赖故障还是资源瓶颈

只有明确报错类型、触发条件、影响范围后,才能进行下一步处理或优化。


二、接口性能优化:从瓶颈到提速的常用手段

线上最常见的问题之一就是接口响应慢、吞吐量低、高并发下雪崩,这类问题大多与资源使用不合理、逻辑冗余有关。通用优化思路如下:

2.1 增加缓存,减少数据库访问

缓存是提升接口性能最直接、成本最低的手段之一,尤其适用于读多写少的场景。

  • 本地缓存:Caffeine、Guava Cache,适用于单机、数据量小、一致性要求不高的场景
  • 分布式缓存:Redis,支持高可用、分布式、过期策略、高并发读取
  • 缓存思路:热点数据、配置数据、字典数据、用户基础信息提前缓存,避免频繁查询 DB

2.2 添加索引,优化 SQL 执行效率

绝大多数接口慢都源于慢 SQL,而慢 SQL 大多是缺少索引或索引失效导致。

  • 为查询条件字段建立合理索引(where、group by、order by 字段)
  • 避免左模糊、函数运算、类型隐式转换导致索引失效
  • 使用执行计划 explain 分析 SQL 执行效率,定位全表扫描
  • 大表分页优化:延迟关联、主键分页

2.3 使用多线程池处理 IO 密集型任务

IO 密集型场景(调用第三方接口、文件读写、消息发送、多 DB 查询)适合线程池异步化处理。

  • 使用 ThreadPoolExecutor 自定义线程池,避免滥用 Executors
  • 异步并行执行无依赖的多个 IO 操作,显著降低 RT
  • 配合 Future/CompletableFuture 实现结果聚合
  • 注意线程池参数、拒绝策略、上下文传递、事务一致性

三、常见线上问题深度排查

线上问题类型繁多,其中 CPU 飙升、死锁 是高频且危害较大的场景,下面详细说明定位与解决方法。

3.1 CPU 飙升问题排查

CPU 飙升表现为服务器 CPU 使用率持续 100%,服务响应极慢甚至假死,常见原因:死循环、频繁 GC、复杂计算、大量线程阻塞与争抢。

排查步骤
  1. 定位高 CPU 进程使用 top 命令找到 CPU 占用最高的进程 PID:
bash 复制代码
top
  1. 定位高耗 CPU 线程
bash 复制代码
top -H -p 进程PID

找到占用 CPU 最高的线程 ID,并转换为 16 进制(用于 jstack 匹配)。

  1. 导出线程栈
bash 复制代码
jstack 进程PID > stack.log

在日志中搜索 16 进制线程 ID,定位具体代码行。

  1. 分析原因
  • 死循环:代码逻辑错误,无限循环执行
  • 频繁 GC:内存不足、对象创建过多、FullGC 频繁
  • 复杂计算:大量正则、递归、加密解密、数据解析
  • 锁竞争:大量线程等待锁,导致频繁上下文切换
解决方案
  • 修复死循环、优化复杂计算逻辑
  • 调整 JVM 参数,优化内存使用
  • 优化锁设计,减少锁竞争
  • 异步化、限流、削峰,降低瞬时压力

3.2 死锁问题排查

死锁是指两个或多个线程互相持有对方需要的资源,并且互不释放,导致线程永久阻塞,服务无法响应。

死锁典型表现
  • 接口持续阻塞不返回
  • 数据库层面出现锁等待
  • 线程栈中显示 BLOCKED 状态并循环等待
快速解决方式
  1. 紧急恢复:重启服务 在业务影响较大时,重启服务可以快速打破死锁,恢复可用,属于应急止血手段。但重启只能临时解决,无法根除问题。

  2. 根因解决:开发者调整资源分配从代码层面彻底避免死锁:

  • 统一资源获取顺序,避免循环等待
  • 避免在事务中嵌套远程调用、长耗时操作
  • 使用定时锁(tryLock),避免无限等待
  • 减少锁粒度,使用分段锁、无锁编程
  • 数据库层面避免长事务,合理设置事务超时
  • 通过 jstackjconsole 分析死锁线程,定位代码位置
排查工具
  • jstack:直接搜索 deadlock 关键字
  • jconsole /jvisualvm:可视化检测死锁
  • MySQL show engine innodb status:数据库死锁分析

四、总结

线上问题排查没有银弹,但有固定章法:

  1. 先看日志,定位异常,这是所有排查的起点;
  2. 性能问题优先从缓存、索引、异步线程池切入优化;
  3. CPU 飙升用系统命令 + 线程栈定位代码;
  4. 死锁优先重启止血,再从资源申请顺序与锁设计根治。

保持冷静、按步骤排查、先恢复再优化,既能最大程度降低业务影响,也能逐步形成自己的线上问题处理体系。

相关推荐
摇滚侠39 分钟前
VMvare 虚拟机 Oracle19c 安装步骤,远程连接 Oracle19c,百度网盘安装包
java·oracle
梁萌43 分钟前
idea报错找不到XX包的解决方法
java·intellij-idea·启动报错·缺少包
Agent产品评测局1 小时前
生产排期与MES/ERP系统打通,实操方法详解 —— 2026企业级智能体自动化选型与实战指南
java·运维·人工智能·ai·chatgpt·自动化
阿丰资源1 小时前
基于Spring Boot的电影城管理系统(直接运行)
java·spring boot·后端
呱牛do it1 小时前
企业级门户网站设计与实现:基于SpringBoot + Vue3的全栈解决方案(Day 8)
java
消失的旧时光-19432 小时前
Spring Boot 工程化进阶:统一返回 + 全局异常 + AOP 通用工具包
java·spring boot·后端·aop·自定义注解
NE_STOP2 小时前
Redis--发布订阅命令和Redis事务
java
PAC_3Dame2 小时前
记一次真实的线上OOM
java
SunnyDays10113 小时前
如何在Java中将Word文档转换为图像(JPEG、PNG或SVG)
java
Lumos_7773 小时前
Linux -- 线程
java·jvm·算法