当前位置: 首页 > news >正文

Java 线上问题排查:从基础到高级的全面指南

非常抱歉给你带来了不好的体验!首先,关于格式问题,我会重新调整排版,使用更清晰的分级标题、列表和段落分隔,让内容更易读;其次,之前内容确实未完整生成,现在会按照原文完整呈现,确保不遗漏任何部分。以下是重新整理且完整的内容:

Java 线上问题排查:从基础到高级的全面指南

一、线上问题的基本分类与特征

在 Java 应用的生产环境中,问题表现形式多种多样,但可以归纳为几类典型问题。了解这些问题的基本分类和特征,是快速定位和解决问题的基础。

1.1 资源相关问题

资源相关问题是线上最常见的问题类型,主要涉及 CPU、内存、磁盘和网络资源的使用异常。

  • CPU 使用率过高
    • 特征:服务器响应变慢,系统负载升高,通过top命令查看发现 Java 进程 CPU 占用率持续超过 80%。
    • 可能原因:死循环、频繁 GC、大量计算操作、线程竞争等。
    • 典型场景:电商促销期间,订单处理服务 CPU 使用率飙升至 99%,导致响应延迟增加。
  • 内存溢出(OOM)
    • 特征:应用突然崩溃,日志中出现java.lang.OutOfMemoryError异常,系统可用内存急剧下降。
    • 可能原因:内存泄漏、堆内存设置过小、对象创建过多且未及时释放等。
    • 典型场景:日志服务因未正确关闭日志文件句柄,导致内存持续增长最终溢出。
  • 磁盘问题
    • 特征:应用写入日志或数据文件时速度变慢,df -h命令显示磁盘空间不足或使用率 100%。
    • 可能原因:日志文件过大未清理、临时文件未删除、磁盘硬件故障等。
    • 典型场景:监控系统因日志保留策略不当,导致磁盘空间被耗尽,服务无法写入新日志。
  • 网络问题
    • 特征:服务间调用超时增加,ping命令响应时间延长,TCP 连接异常断开。
    • 可能原因:网络带宽不足、防火墙配置错误、DNS 解析问题等。
    • 典型场景:微服务架构中,因网络波动导致服务间调用频繁超时,引发连锁反应。

1.2 性能相关问题

性能相关问题通常表现为响应时间延长、吞吐量下降,但应用仍在运行,未完全崩溃。

  • 接口响应变慢
    • 特征:用户反馈操作响应慢,监控显示接口平均响应时间(RT)明显增加,如从 50ms 增加到 500ms。
    • 可能原因:数据库查询变慢、第三方服务调用延迟、代码逻辑复杂度过高。
    • 典型场景:电商搜索服务在商品数量增加后,未优化的模糊查询导致响应时间延长。
  • 线程池满
    • 特征:日志中出现线程池拒绝执行任务的警告,应用吞吐量明显下降。
    • 可能原因:任务处理时间过长、线程池配置不合理、并发请求量突增。
    • 典型场景:秒杀活动期间,订单服务线程池因处理能力不足而被耗尽。
  • GC 频繁或耗时过长
    • 特征:GC 日志显示频繁的 Young GC 或长时间的 Full GC,应用出现明显的停顿。
    • 可能原因:堆内存分配不合理、内存泄漏、大对象频繁创建。
    • 典型场景:未正确设置 JVM 参数的 Web 应用,在高并发下频繁触发 Full GC,导致服务卡顿。

1.3 功能相关问题

功能相关问题是指应用虽然运行正常,但某些功能无法按预期工作,可能涉及业务逻辑、数据一致性等问题。

  • 业务逻辑异常
    • 特征:日志中出现业务异常,如NullPointerExceptionIllegalArgumentException等,但应用未崩溃。
    • 可能原因:参数校验不充分、业务流程设计缺陷、数据状态不一致。
    • 典型场景:用户积分系统中,因未正确处理并发更新导致积分扣减异常。
  • 数据不一致
    • 特征:数据库、缓存、文件等不同数据源中的数据不一致,业务操作出现异常结果。
    • 可能原因:事务处理不当、缓存更新策略错误、异步操作未正确同步。
    • 典型场景:订单系统中,数据库已更新但缓存未及时更新,导致用户看到不一致的订单状态。
  • 分布式事务问题
    • 特征:涉及多个服务的业务操作部分成功、部分失败,数据处于中间状态。
    • 可能原因:分布式事务协调机制失效、网络中断、补偿机制未正确实现。
    • 典型场景:跨多个微服务的订单创建和库存扣减操作,因网络问题导致库存已扣但订单未创建。

1.4 基础设施与环境问题

基础设施与环境问题通常由服务器、网络、中间件等底层组件引起,影响应用的正常运行。

  • 依赖服务不可用
    • 特征:应用日志中出现大量与数据库、缓存、消息队列等连接失败的异常。
    • 可能原因:数据库宕机、Redis 服务中断、消息队列服务崩溃等。
    • 典型场景:电商支付服务因第三方支付接口不可用,导致大量支付请求失败。
  • 配置错误
    • 特征:应用启动失败或某些功能异常,日志中出现与配置相关的错误。
    • 可能原因:配置文件错误、环境变量设置不当、配置中心同步失败。
    • 典型场景:因数据库连接字符串配置错误,导致应用无法连接数据库。
  • 权限问题
    • 特征:应用无法读写文件、访问网络端口,出现Permission Denied等错误。
    • 可能原因:文件权限设置错误、用户权限不足、SELinux 或 AppArmor 限制。
    • 典型场景:应用因没有写入权限而无法创建日志文件。

二、线上问题排查的基本原则

面对线上问题,遵循科学的排查原则可以提高效率,避免因操作不当导致问题扩大或复杂化。

2.1 先恢复后排查

  • 核心原则:在生产环境中,应优先恢复服务可用性,再进行详细排查和修复。
  • 快速响应
    当发现服务异常时,首先评估问题影响范围和严重程度,判断是否需要立即采取恢复措施。
    对于影响核心业务的严重问题,如服务完全不可用,应立即启动应急预案,而不是花费时间详细分析。
  • 临时解决方案
    可采取降级、限流、切换备用服务等临时措施,尽快恢复服务的基本功能。
    示例:电商支付服务出现性能问题时,可暂时关闭部分非核心校验逻辑,提高处理速度。
  • 恢复与记录并重
    在采取恢复措施的同时,详细记录操作步骤和时间点,便于后续分析和复盘。
    示例:记录降级时间、切换的备用服务、调整的配置参数等关键信息。

2.2 系统化排查方法

  • 核心原则:采用系统化的排查方法,从宏观到微观,逐步缩小问题范围。
  • 分层排查
    按照 “业务表现 → 应用服务 → 中间件 → 数据库 → 基础设施” 的顺序进行排查。
    示例:用户反馈支付失败时,先检查支付接口返回状态,再查看应用日志,接着检查数据库操作,最后确认支付网关是否正常。
  • 数据驱动
    基于监控数据、日志信息、性能指标等客观数据进行分析,避免主观臆断。
    示例:通过 APM 工具查看接口调用链路的耗时分布,确定性能瓶颈所在。
  • 假设验证
    基于已有信息提出可能的原因假设,然后通过进一步收集数据来验证或排除假设。
    示例:假设数据库慢查询是接口响应慢的原因,通过分析慢查询日志来验证。

2.3 保持环境一致性

  • 核心原则:在排查过程中,保持生产环境的稳定性和一致性,避免引入新的变量。
  • 避免在生产环境直接调试
    不要在生产环境中添加调试代码、修改业务逻辑或进行复杂的诊断操作。
    示例:不要在生产环境中添加System.out.println语句或修改核心业务逻辑。
  • 最小变更原则
    每次排查操作应尽可能小且可逆,以便在发现问题时能够快速回退。
    示例:调整 JVM 参数时,一次只调整一个参数,并记录调整前后的状态。
  • 环境隔离
    如果需要复现问题,应在与生产环境尽可能一致的测试环境中进行。
    示例:使用生产数据的脱敏副本在测试环境中复现问题,分析原因。

2.4 记录与复盘

  • 核心原则:详细记录排查过程和结果,定期进行复盘,不断完善问题处理流程。
  • 详细记录
    记录问题现象、时间、影响范围、排查步骤、收集的数据、采取的措施等所有相关信息。
    示例:创建专门的问题跟踪文档,记录每一步操作和观察到的结果。
  • 问题分类与归因
    对问题进行分类(如性能问题、功能异常、基础设施故障等),分析根本原因。
    示例:将支付接口响应慢的问题归因于数据库索引缺失导致的慢查询。
  • 经验总结与分享
    总结问题排查过程中的经验教训,分享给团队成员,提高整体故障处理能力。
    示例:在团队内部分享如何通过 APM 工具快速定位分布式系统中的性能瓶颈。
  • 预防措施
    根据问题原因,制定预防措施,如增加监控指标、完善自动化测试、优化代码等。
    示例:针对数据库慢查询问题,增加慢查询日志监控和自动报警机制。

三、线上问题排查的通用流程

面对线上问题,遵循标准化的排查流程可以提高效率,确保不遗漏关键步骤。以下是一个通用的线上问题排查流程。

3.1 问题确认与初步评估

第一步:确认问题现象和影响范围
  • 收集信息
    通过监控系统、用户反馈、日志系统等渠道收集问题相关信息。
    关键信息包括:问题发生时间、影响的用户群体、具体错误现象、错误频率等。
  • 初步判断
    根据收集的信息,初步判断问题类型(资源问题、性能问题、功能问题等)。
    评估问题的严重程度和影响范围,确定是否需要立即采取恢复措施。
  • 示例
    用户反馈支付页面加载缓慢,通过监控发现支付接口的平均响应时间从 50ms 增加到 2 秒,错误率上升至 15%。
    初步判断为性能问题,影响所有尝试支付的用户,属于严重问题,需要立即处理。

3.2 快速恢复服务

第二步:采取紧急恢复措施
  • 启动应急预案
    根据问题类型和严重程度,启动相应的应急预案。
    可能的恢复措施包括:服务降级、限流、切换到备用服务、重启应用等。
  • 执行恢复操作
    按照既定的应急预案执行恢复操作,确保核心业务功能可用。
    示例:针对支付接口性能问题,暂时关闭非核心的风险控制检查,提高处理速度。
  • 验证恢复效果
    检查服务是否已恢复正常,监控关键指标是否回归正常水平。
    示例:确认支付接口响应时间是否降至可接受范围,错误率是否下降。

3.3 详细数据收集

第三步:全面收集问题相关数据
  • 监控数据分析
    收集系统资源(CPU、内存、磁盘、网络)使用情况的监控数据。
    收集应用性能指标(响应时间、吞吐量、错误率)的监控数据。
  • 日志分析
    收集应用日志、错误日志、业务日志等相关日志信息。
    重点关注问题发生前后的日志记录,查找异常堆栈、错误信息等。
  • 应用状态检查
    检查应用的运行状态,如线程池状态、连接池使用情况、缓存状态等。
    示例:通过 JMX 或 Spring Actuator 端点查看应用内部状态。
  • 示例
    收集支付接口的监控数据,发现数据库连接池使用率达到 100%,执行show processlist发现大量等待锁的查询。
    查看应用日志,发现频繁的数据库连接超时和死锁异常。

3.4 问题定位与分析

第四步:深入分析,定位问题根源
  • 分析收集的数据
    综合监控数据、日志信息和应用状态,进行深入分析。
    示例:分析数据库慢查询日志,发现一条未加索引的查询语句执行时间超过 2 秒。
  • 假设验证
    根据分析结果,提出可能的原因假设,并设计验证方法。
    示例:假设索引缺失是导致数据库查询慢的原因,通过执行EXPLAIN语句验证查询执行计划。
  • 逐步排除
    从可能性最高的假设开始,逐一排除或验证,缩小问题范围。
    示例:先验证数据库索引问题,再检查应用代码逻辑,最后确认第三方服务是否正常。
  • 示例
    通过分析数据库慢查询日志和执行计划,确认支付接口中的订单查询语句因缺少索引导致性能下降。
    进一步检查应用代码,发现该查询在高并发场景下被频繁调用,加剧了性能问题。

3.5 问题修复与验证

第五步:实施修复措施并验证效果
  • 制定修复方案
    根据问题根源,制定针对性的修复方案。
    示例:为慢查询语句添加合适的索引,优化查询性能。
  • 实施修复
    在生产环境或测试环境中实施修复措施。
    对于紧急修复,可考虑在生产环境直接实施;对于复杂修复,应先在测试环境验证。
  • 验证修复效果
    监控修复后的系统状态和性能指标,确认问题是否已解决。
    示例:监控支付接口的响应时间和数据库连接池使用率,确认是否恢复正常。
  • 示例
    在数据库中为订单查询字段添加索引,重新部署应用。
    监控显示支付接口平均响应时间降至 80ms,数据库连接池使用率降至正常水平,错误率接近零。

3.6 复盘与预防措施

第六步:总结经验,制定预防措施
  • 问题复盘
    组织团队对问题进行全面复盘,分析问题发生的根本原因、处理过程中的优点和不足。
    示例:复盘支付接口性能问题,发现缺少索引是由于开发阶段未进行充分的性能测试。
  • 记录与分享
    将问题分析过程、修复方案和经验教训整理成文档,分享给团队成员。
    示例:编写《支付接口性能问题处理报告》,详细说明问题原因和解决方法。
  • 制定预防措施
    根据复盘结果,制定针对性的预防措施,防止类似问题再次发生。
    示例:加强开发阶段的性能测试,建立数据库索引审核机制,完善慢查询监控和报警。
  • 持续改进
    完善监控系统和应急预案,提高系统的可观测性和容错能力。
    示例:增加数据库慢查询自动报警功能,优化支付接口的缓存策略。

四、Java 线上问题的排查工具与技术(整体概括)

Java 线上问题排查的核心是“用对工具、精准定位”,围绕 JVM 状态诊断、日志集中分析、全链路性能监控、分布式追踪 四大核心场景,行业内已形成成熟的工具体系。以下从工具分类、核心能力、适用场景三个维度,对这部分内容进行整体概括,帮助快速建立工具认知框架:

一、工具整体分类与核心定位

Java 线上排查工具可分为 4 大类,每类工具聚焦不同问题场景,且常需组合使用(如用 Arthas 定位线程问题,再用 ELK 查关联日志):

工具类别核心解决的问题代表工具核心价值
JVM 监控与诊断工具JVM 内存泄漏、GC 异常、线程死锁、大对象问题jps/jstat/jmap/jstack、VisualVM、JConsole、MAT直接穿透应用层,获取 JVM 底层运行状态,是“内存/线程类问题”的根本定位手段
日志分析工具分散日志集中管理、异常日志快速检索、日志趋势可视化Log4j/Logback(日志输出)、ELK Stack、Graylog、Splunk将“碎片化日志”转化为“可查询线索”,是排查功能异常、业务报错的核心依据
性能分析与 APM 工具接口响应慢、CPU 使用率高、吞吐量下降、全链路性能瓶颈Arthas、Async Profiler、SkyWalking、Pinpoint、New Relic从“代码方法”到“跨服务链路”,分层定位性能瓶颈,解决“不知道慢在哪”的问题
分布式追踪工具微服务架构下跨服务调用超时、链路数据不一致、责任归属不清Zipkin、Jaeger、SkyWalking(含追踪能力)、Dapr为分布式请求生成“全局 traceID”,串联多服务调用链路,定位跨服务问题根源

二、各类工具的核心能力与适用场景

1. JVM 监控与诊断工具:聚焦“JVM 底层问题”

这类工具是 Java 排查的“基础工具集”,直接与 JVM 交互,核心解决 “应用层看不到的底层问题”,比如内存泄漏、GC 频繁、线程阻塞等。

  • 轻量级命令行工具(jps/jstat/jmap/jstack)
    • 特点:无依赖、随 JDK 自带,适合服务器端快速执行(无需安装图形化工具);
    • 核心能力:
      • 快速查进程(jps)、看 GC 统计(jstat)、导堆快照(jmap)、抓线程栈(jstack);
      • 典型场景:服务器 CPU 飙升时,用 jstack <pid> 抓线程栈,快速定位死循环/高 CPU 线程;内存溢出前,用 jmap 导堆快照备用。
  • 图形化监控工具(VisualVM、JConsole)
    • 特点:可视化界面,操作直观,适合开发/运维实时监控;
    • 核心能力:实时看内存/线程趋势、手动触发 GC、检测死锁、查看 JVM 参数;
    • 典型场景:本地开发环境监控应用启动过程,或远程连接测试环境,观察 JVM 内存变化是否正常。
  • 深度堆分析工具(MAT)
    • 特点:专注“堆快照深度分析”,是内存泄漏的“终极定位工具”;
    • 核心能力:自动识别泄漏嫌疑对象、展示对象引用链(GC Roots)、分析大对象占比;
    • 典型场景:应用发生 OOM 后,导入堆快照文件,定位“哪些对象没被回收、为什么没被回收”(如静态集合持有过期数据)。
2. 日志分析工具:聚焦“日志线索整合”

日志是线上问题的“第一手线索”,但分布式环境下日志分散在多台服务器,这类工具的核心是 “把分散日志变集中、变可查、变可用”

  • 日志输出框架(Log4j 2、Logback + SLF4J)
    • 定位:“日志生产端”工具,负责规范日志输出格式、级别、目的地;
    • 核心能力:支持异步日志(避免日志阻塞业务)、日志轮转(防止磁盘占满)、关联 traceID(便于分布式追踪);
    • 关键要求:生产环境日志必须包含“时间戳、traceID、线程ID、日志级别、业务参数”,否则后续无法有效查询。
  • 集中式日志平台(ELK Stack、Graylog、Splunk)
    • 定位:“日志消费端”工具,负责日志的收集、存储、查询、可视化;
    • 核心差异:
      • ELK:开源、灵活、生态完善,但配置复杂,适合中大型团队;
      • Graylog:开源、配置简单,适合中小型团队快速上手;
      • Splunk:商业工具,功能强(含 AI 诊断、合规审计),适合大型企业;
    • 典型场景:用户反馈“支付失败”,通过 ELK 搜索“支付相关 traceID”,快速找到支付服务的 ERROR 日志,定位是“第三方接口超时”还是“数据库插入失败”。
3. 性能分析与 APM 工具:聚焦“性能瓶颈定位”

性能问题(如接口 RT 高、吞吐量低)的难点是“不知道瓶颈在代码、还是在数据库、还是在第三方服务”,这类工具的核心是 “分层拆解性能耗时,精准定位瓶颈点”

  • 轻量级性能诊断工具(Arthas、Async Profiler)
    • 特点:无侵入(无需重启应用)、聚焦“代码层性能”,是线上性能问题的“快速定位工具”;
    • 核心能力:
      • Arthas:实时看 JVM 仪表盘、追踪方法调用耗时(trace 命令)、查看方法入参/返回值(watch 命令)、生成 CPU 火焰图;
      • Async Profiler:更轻量的 CPU/内存采样工具,生成的火焰图更精准,适合高并发场景(性能开销<1%);
    • 典型场景:订单接口 RT 从 50ms 升至 500ms,用 Arthas 的 trace 命令追踪,发现是“订单查询方法未走缓存,每次查数据库”导致。
  • 全链路 APM 工具(SkyWalking、Pinpoint、New Relic)
    • 特点:聚焦“分布式架构下的全链路性能”,从“单个接口”扩展到“跨服务链路”;
    • 核心能力:
      • 链路拓扑:可视化展示“网关→订单服务→库存服务→数据库”的调用关系;
      • 耗时拆解:统计每个服务/每个方法的耗时占比(如“库存服务占总耗时 60%”);
      • 异常告警:当接口 RT 超阈值、错误率上升时,自动触发告警;
    • 典型场景:微服务架构下,用户下单响应慢,通过 SkyWalking 看到“库存服务调用 Redis 超时”,进而定位是 Redis 集群负载过高。
4. 分布式追踪工具:聚焦“跨服务问题定位”

微服务架构下,一个请求会经过多个服务,这类工具的核心是 “用全局 traceID 串联多服务调用链路,明确问题归属”

  • 代表工具:Zipkin(轻量开源)、Jaeger(云原生友好)、SkyWalking(APM+追踪一体化);
  • 核心逻辑:
    1. 请求进入系统时,生成唯一 traceID;
    2. 每个服务调用时,通过 HTTP 头/RPC 元数据传递 traceID;
    3. 每个服务将“调用耗时、状态”上报给追踪平台;
    4. 平台通过 traceID 聚合所有服务的调用数据,生成完整链路图;
  • 典型场景:用户下单后“订单创建成功但库存未扣减”,通过 traceID 查看链路,发现“订单服务调用库存服务时,网络超时导致库存服务未收到请求”,明确是网络层问题。

三、工具选择与组合使用原则

  1. 按问题场景选工具

    • 内存泄漏/OOM:先⽤ jmap 导堆快照,再用 MAT 分析;
    • 线程死锁/CPU 高:用 jstack 抓线程栈,或 Arthas 的 thread -b 定位;
    • 分布式接口超时:用 SkyWalking/Zipkin 查链路,再用 ELK 查对应服务日志;
    • 代码层性能慢:用 Arthas 的 trace 或 Async Profiler 生成火焰图。
  2. 工具组合优于单一工具
    例如排查“支付接口慢”:

    1. 先用 APM 工具(如 SkyWalking)看全链路耗时,发现“支付服务调用数据库慢”;
    2. 再用 Arthas 连接支付服务,trace 数据库查询方法,确认是“SQL 未走索引”;
    3. 最后用 ELK 搜索该 SQL 相关日志,查看是否有大量重复执行,验证问题影响范围。
  3. 兼顾“轻量”与“精准”

    • 线上紧急问题:优先用轻量工具(jstack、Arthas)快速止血;
    • 复杂慢性问题(如内存泄漏):再用重量级工具(MAT、Splunk)深度分析。

通过以上工具体系,可覆盖 Java 线上从“JVM 底层”到“分布式链路”的绝大多数问题场景,核心是理解“每类工具的定位”,并根据实际问题灵活组合,避免“用错工具导致排查效率低下”。

以下通过 5 个典型线上问题场景,结合具体工具和操作步骤,演示 Java 线上问题排查的实践过程,帮助理解工具的实际应用:

场景 1:应用频繁 Full GC,导致服务卡顿

问题现象:用户反馈系统每隔几分钟就卡顿一次,监控显示 Full GC 频繁(每 2 分钟一次),每次耗时 3-5 秒。
排查目标:定位 Full GC 频繁的原因(内存泄漏/堆配置不合理/大对象)。

实践步骤:
  1. 用 jstat 确认 GC 状态
    执行命令:jstat -gcutil <pid> 1000 10(每 1 秒输出一次 GC 统计,共 10 次)
    输出结果示例:

    S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
    0.00  50.00  30.00  98.00  90.00  85.00    120    5.200     15    28.500   33.700
    

    分析:老年代(O)使用率 98%,FGC 次数 15 次,FGCT 总耗时 28.5 秒,说明老年代内存不足,导致频繁 Full GC。

  2. 用 jmap 分析堆内存分布
    执行命令:jmap -histo:live <pid> | head -20(查看存活对象Top 20)
    输出结果示例:

    num     #instances         #bytes  class name
    ----------------------------------------------
    1:         500000      80000000  com.example.UserSession
    2:          20000      16000000  [B
    3:          15000       9600000  java.lang.String
    

    分析:UserSession 实例达 50 万个,占用 80MB 内存,怀疑是会话未及时清理。

  3. 用 MAT 深度分析堆快照

    • 导出堆快照:jmap -dump:format=b,file=heap.hprof <pid>
    • 用 MAT 打开 heap.hprof,查看“Dominator Tree”:
      发现 UserSession 对象被 com.example.SessionManager 的静态变量 sessionMap 持有,且大部分 UserSessionlastAccessTime 是 24 小时前(已过期)。
    • 结论:会话管理未实现过期清理机制,导致老年代被占满,触发频繁 Full GC。
  4. 解决措施
    SessionManager 中添加定时任务,清理 30 分钟未活跃的 UserSession,重启应用后 Full GC 频率降至每 2 小时一次,服务卡顿消失。

场景 2:接口响应突然变慢(从 50ms 升至 1s)

问题现象:订单查询接口响应时间突增,监控显示接口 RT 从 50ms 升至 1s 以上,无报错日志。
排查目标:定位接口内部哪个步骤耗时增加。

实践步骤:
  1. 用 Arthas 追踪方法耗时
    执行命令:trace com.example.OrderService queryOrder "{params, returnObj, costTime}" -n 5(追踪 queryOrder 方法,输出前 5 次调用的参数、返回值和耗时)
    输出结果示例:

    `---ts=2023-10-01 10:00:00;thread_name=http-nio-8080-exec-1;id=1;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@123456
    `---[1020ms] com.example.OrderService:queryOrder()+---[980ms] com.example.OrderDao:selectById()  // 数据库查询耗时占比 96%+---[5ms] com.example.CacheService:get()`---returnObj=Order(id=123, ...)
    

    分析:OrderDao.selectById() 耗时 980ms,是性能瓶颈。

  2. 检查数据库慢查询
    查看数据库慢查询日志(假设 MySQL,已开启 slow_query_log),发现 SQL:
    SELECT * FROM order WHERE user_id = 123;(执行时间 970ms)
    EXPLAIN 分析:user_id 字段未建索引,导致全表扫描(表数据量 100 万行)。

  3. 解决措施
    order 表的 user_id 字段添加索引,重新执行 SQL 耗时降至 10ms,接口 RT 恢复至 30ms。

场景 3:线程死锁导致服务无响应

问题现象:用户提交订单后无响应,应用日志停止输出,top 命令显示 Java 进程 CPU 使用率 10%(正常),但线程数异常高(500+)。
排查目标:确认是否存在线程死锁。

实践步骤:
  1. 用 jstack 抓线程栈
    执行命令:jstack <pid> > thread.log,查看 thread.log
    发现死锁提示:

    Found one Java-level deadlock:
    =============================
    "Thread-1":waiting to lock monitor 0x00007f1234567890 (object 0x000000076ab12345, a java.lang.Object),which is held by "Thread-2"
    "Thread-2":waiting to lock monitor 0x00007f123456abcd (object 0x000000076ab54321, a java.lang.Object),which is held by "Thread-1"
    

    分析:Thread-1Thread-2 互相持有对方需要的锁,导致死锁。

  2. 定位死锁代码
    从线程栈中找到具体代码行:

    • Thread-1 栈信息:at com.example.OrderService.updateStatus(OrderService.java:156)(持有锁 A,等待锁 B)
    • Thread-2 栈信息:at com.example.OrderService.updateAmount(OrderService.java:203)(持有锁 B,等待锁 A)
      查看代码发现:两个方法分别以“锁 A→锁 B”和“锁 B→锁 A”的顺序获取锁,导致高并发下死锁。
  3. 解决措施
    统一锁获取顺序(均按“锁 A→锁 B”获取),重启应用后死锁消失,服务恢复响应。

场景 4:分布式链路调用超时(微服务架构)

问题现象:用户下单后提示“系统繁忙”,APM 工具显示“订单服务→库存服务”调用超时(5 秒未响应)。
排查目标:确定超时是库存服务自身慢,还是网络问题,还是下游依赖问题。

实践步骤:
  1. 用 SkyWalking 查看全链路追踪
    在 SkyWalking 控制台搜索该请求的 traceID,链路图显示:

    • 订单服务→库存服务:耗时 5000ms(超时)
    • 库存服务内部:checkStock 方法耗时 4900ms
      分析:超时发生在库存服务内部,非网络问题。
  2. 用 ELK 查库存服务日志
    在 Kibana 中搜索 service:stock-service AND traceID:xxx,发现日志:
    [ERROR] [checkStock] 调用 Redis 超时,key=stock:123, cost=4900ms
    分析:库存服务查询 Redis 超时,导致整体调用超时。

  3. 检查 Redis 状态
    执行 redis-cli info stats 查看 Redis 状态,发现 total_commands_processed 突增,instantaneous_ops_per_sec 达 10 万+(远超 Redis 承载能力),且存在大量 KEYS * 命令(耗时操作)。
    定位:某定时任务每 10 秒执行一次 KEYS * 扫描全量键,导致 Redis 阻塞。

  4. 解决措施
    KEYS * 替换为 SCAN 分批扫描,Redis 性能恢复,库存服务调用耗时降至 20ms,下单流程正常。

场景 5:应用内存泄漏(OOM 前预警)

问题现象:监控显示应用老年代内存持续增长(每天增加 100MB),无明显下降,预计 3 天后会 OOM。
排查目标:找到内存泄漏的对象及原因。

实践步骤:
  1. 对比不同时间点的堆快照

    • 第一天导出堆快照:jmap -dump:format=b,file=heap1.hprof <pid>
    • 第二天同一时间导出堆快照:jmap -dump:format=b,file=heap2.hprof <pid>
    • 用 MAT 对比两个快照(“Compare Heap Dumps”功能),发现 com.example.LogFile 实例从 100 个增至 10000 个,内存占用增加 90MB。
  2. 分析 LogFile 对象引用链
    在 MAT 中查看 LogFile 的“Path To GC Roots”,发现其被 com.example.LogManagerfiles 集合持有,且 LogFileinputStream 未关闭(文件句柄泄漏)。
    代码定位:LogManager 打开日志文件后,仅读取内容但未调用 close() 方法,导致 LogFile 对象无法被 GC 回收。

  3. 解决措施
    LogFile 类中添加 try-with-resources 自动关闭流,修复后老年代内存不再增长,避免 OOM 发生。

总结:实践排查的核心思路

  1. 先看监控定方向:通过 APM、GC 监控、系统指标(CPU/内存)快速锁定问题大类(性能/内存/线程/分布式)。
  2. 工具组合找线索:命令行工具(jstack/jmap)快速定位,图形化工具(MAT/Arthas)深度分析,日志平台(ELK)关联上下文。
  3. 从现象到代码:通过工具定位到具体方法/SQL/依赖,再结合代码逻辑找到根本原因(如锁顺序错误、资源未释放、索引缺失)。

每个问题的排查都是“现象→工具→数据→结论”的循环,熟练掌握工具的核心命令和分析方法,能大幅提升排查效率。


文章转载自:

http://zNGRM7Gw.ypdwc.cn
http://UW0hXm6j.ypdwc.cn
http://RgSkDLlH.ypdwc.cn
http://5QFIRebM.ypdwc.cn
http://wGJtXmjJ.ypdwc.cn
http://pbfnD0tx.ypdwc.cn
http://LFhIrAWS.ypdwc.cn
http://MOGTKPZ6.ypdwc.cn
http://WAH7FL4p.ypdwc.cn
http://6pTGrBv5.ypdwc.cn
http://JaMiBMiB.ypdwc.cn
http://HtVntrOV.ypdwc.cn
http://MU8C8q4t.ypdwc.cn
http://IiNlsV2b.ypdwc.cn
http://HNv8UaOa.ypdwc.cn
http://j3W1VtS0.ypdwc.cn
http://rAIkBnDr.ypdwc.cn
http://T1QBrtZY.ypdwc.cn
http://xdu4z7a5.ypdwc.cn
http://9oxfywV8.ypdwc.cn
http://tASUqmXV.ypdwc.cn
http://2iy4Th7B.ypdwc.cn
http://gVz73rSW.ypdwc.cn
http://T6OhbO2L.ypdwc.cn
http://glfyBdzL.ypdwc.cn
http://8jvVERJS.ypdwc.cn
http://X669y8s0.ypdwc.cn
http://0Y6ugsEO.ypdwc.cn
http://YnehhaA9.ypdwc.cn
http://5VvFbSdo.ypdwc.cn
http://www.dtcms.com/a/379588.html

相关文章:

  • 浅谈Nacos配置中心
  • 美国CISA发布通用漏洞披露 (CVE) 计划愿景
  • 软考中级习题与解答——第五章_面向对象方法(1)
  • 硬件驱动——I.MX6ULL裸机启动(2)
  • Linux 进程深度解析(6):资源隔离的底层实现 (Namespace、Cgroups 与容器化)
  • 【AI大模型面试宝典60题】1-5
  • AUTOSAR Adaptive Platform 日志与追踪 (Log and Trace) 规范深度解析
  • Claude Code + 自定义模型体验
  • Python 实战:票据图像自动矫正技术拆解与落地教程
  • 【Kubernetes】常见面试题汇总(十四)
  • 【 Rank(列)、DIMM(内存条) 和 DDR颗粒(内存芯片) 的区别】
  • 密钥协商与前向/后向安全性
  • UART 总线核心特性
  • CDN(Content Delivery Network,内容分发网络)
  • EMC电磁兼容进阶3讲培训:专题二 电源线滤波器仿真实践-基于反激电源
  • 2.DSP学习记录之GPIO输出应用实验
  • WSL2 | 一种临时解决在 Windows 10 运行了一段时间 WSL2 之后 WSL2 无响应的方法
  • SPARC方法论在Claude Code基于规则驱动开发中的应用
  • Python编程基础(九) | 文件和异常
  • AWS IAM条件操作符实战指南:从基础到高级应用
  • SW - 无法用此剖切线来剖切此模型/零部件。请确认该剖切线完全通过该模型。
  • 【主页介绍】
  • 数据治理进阶——解读2024 企业数据治理体系和应用场景案例【附全文阅读】
  • 测试的概念
  • Python生物信息学数据处理大全:从FASTA文件到Pandas DataFrame
  • Android 设置禁止截图和禁止长截图
  • VR煤矿实训系统相较于传统煤矿培训方式的独特优势​-广州华锐互动
  • 鸿蒙Next Web组件详解:属性设置与事件处理实战
  • Chaosblade常用命令和范例
  • Linux内存管理章节九: 打通虚拟与实体的桥梁:深入Linux内存映射机制