
在软件开发的生命周期中线上环境出现问题是不可避免的。无论是接口报错、请求超时还是CPU飙升、内存溢出快速定位并解决这些问题是对开发人员的重要考验。本文将系统梳理常见的线上问题类型及其排查方法并结合实际工具如Arthas、jstack、ELK等给出操作指南帮助你在生产环境中从容应对各种故障。一、问题定位的通用流程当线上系统出现异常时通常遵循以下步骤进行排查收集信息查看监控告警、日志、用户反馈初步判断问题现象接口报错、超时、卡死、OOM等。复现问题尝试在测试环境复现或通过日志、监控数据确认触发条件。定位根源使用日志分析、线程堆栈、内存快照等手段找到问题代码或配置。制定方案修改代码、调整参数、扩容资源等。验证与发布在预发环境验证后灰度或全量发布上线。复盘总结记录问题原因及解决过程完善监控和预案。下面针对不同问题类型详细介绍排查方法。二、接口报错与RT超时现象接口返回500、404等错误码请求耗时过长甚至超时Request Timeout排查思路1. 直接查看应用日志大多数应用都会将运行日志输出到文件如Tomcat的logs目录、Spring Boot的logs/文件夹。通过grep、tail等命令快速定位错误发生时的堆栈信息。# 实时查看日志 tail -f /path/to/logs/application.log # 搜索错误关键词 grep ERROR application.log | grep 接口名如果系统是分布式微服务架构日志会分散在多台机器上此时需要集中式日志系统如ELKElasticsearch Logstash Kibana或Spring Boot Admin。2. ELK日志采集架构简单架构Logstash采集各节点日志 → Elasticsearch存储 → Kibana展示。高可靠架构引入Kafka作为消息队列避免Logstash故障导致数据丢失。通过Kibana可以快速按时间、服务名、关键字检索日志大大提升排查效率。3. 使用链路追踪对于RT超时问题可能是某个下游服务响应慢或数据库查询慢。此时需要分布式追踪工具如SkyWalking、Zipkin查看调用链各阶段的耗时定位瓶颈。三、程序卡死无报错程序没有报错但请求无响应或响应极慢通常由CPU飙升、内存飙升、死锁等原因引起。3.1 CPU飙升问题排查现象系统响应缓慢top命令看到CPU使用率接近100%排查步骤原生工具top找出CPU高的进程top记录下进程PID假设为12345。查看进程内CPU高的线程top -H -p 12345记录下高CPU线程的TID十进制。将TID转换为十六进制便于在堆栈中查找printf %x\n TID使用jstack打印线程堆栈jstack -l 12345 jstack.log在jstack.log中搜索十六进制线程ID注意nid格式为0x...即可看到该线程的堆栈信息定位到业务代码。使用Arthas更便捷Arthas 是阿里巴巴开源的Java诊断工具无需修改代码即可在线排查问题。# 启动Arthas java -jar arthas-boot.jar # 选择目标Java进程 # 查看线程CPU占用自动展示最耗CPU的线程 thread # 查看指定线程堆栈 thread 线程ID # 实时监控线程状态 thread -n 3Arthas还提供jad反编译、watch监控方法调用等强大功能是线上排查利器。3.2 死锁问题排查现象程序卡死无报错通过jstack可看到BLOCKED状态的线程且互相等待排查方法原生工具jstack -l pid输出中最后会提示“Found 1 deadlock”并列出死锁线程的详细信息。Arthas# 检测死锁 thread -b输出会直接显示死锁线程及堆栈并指出互相等待的锁对象。四、OOM异常内存溢出4.1 什么是OOMOOMOutOfMemoryError并不单指堆内存溢出而是多种内存区域溢出的统称常见的有Java heap space堆内存溢出。可能是内存泄漏或堆参数设置过小。PermGen space / Metaspace方法区溢出。通常由动态生成类过多引起如CGLIB、动态代理。Direct buffer memory直接内存溢出如NIO中使用DirectByteBuffer。4.2 问题定位步骤第一步生成堆转储文件在JVM启动参数中加入以下选项当发生OOM时自动导出Heap Dump-XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/path/to/dump.hprof同时建议设置堆大小参数以便复现-Xms512m -Xmx512m。第二步分析堆转储文件使用工具分析生成的.hprof文件Eclipse MAT最常用的内存分析工具可以找出内存泄漏疑点、大对象、对象引用树。VisualVMJDK自带可加载dump文件查看对象统计。JProfiler商业工具功能强大。分析要点查看Histogram按对象大小排序找到占用内存最大的对象。查看Dominator Tree找出根路径上的大对象。分析GC Roots确认是否有意外持有的引用如静态集合、ThreadLocal等。第三步定位问题代码根据对象类型、线程堆栈定位到具体的业务代码。常见原因集合类未清理如List不断添加对象连接资源未释放数据库连接、IO流缓存设计不合理如使用HashMap做缓存且无限增长第三方库内存泄漏如某些HttpClient版本4.3 示例堆内存溢出排查假设OOM日志显示java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:3210) at java.util.ArrayList.grow(ArrayList.java:261) ...通过MAT打开dump发现ArrayList对象占用极大内存查看其引用关系定位到某个业务缓存类未限制大小导致无限添加数据。五、总结与建议1. 建立完善的监控体系应用监控Spring Boot Admin、Prometheus Grafana日志集中ELK、EFK链路追踪SkyWalking、Zipkin2. 养成良好编码习惯使用线程池并合理配置及时释放资源try-with-resources控制集合大小防止无限增长注意静态变量的生命周期3. 掌握必备排查工具Linux命令top、free、df、netstatJDK工具jps、jstack、jmap、jstat、jvisualvm第三方工具Arthas、MAT、Async-profiler4. 故障演练与预案定期进行压力测试、混沌工程实验模拟CPU飙升、OOM等场景检验监控告警和应急响应能力。