线上常见问题案例和排查工具分析

本文为原创内容,转载请注明出处并附带原文链接。感谢您的尊重与支持!

你必须非常努力,才能看起来毫不费劲。


前⾔

这篇⽂章可以作为参考,⽤来准备⾯试中类似下⾯的提问:

  • 你在做这个项⽬的时候遇到了什么问题?(OOM 问题、GC 问题等等)

  • 你⽤过哪些分析定位 Java 故障/性能的⼯具?(JDK ⾃带⼯具、MAT、Arthas 等等)

  • 如果项⽬遇到了 OOM 问题,你会如何排查?(常⽤ MAT)

  • 有什么办法可以监控到 JVM 的实时运⾏状态?(Arthas)

  • ⽣产环境有⼀个接⼝很慢,如何排查?(Arthas)

  • CPU100%,你是怎么处理的?(jstack 或者 Arthas)

  • 你是如何定位线上问题的?(说说⾃⼰了解的⼯具,然后根据⾯试官提示继续深⼊聊即可)

  • 项⽬中遇到了哪些线上故障,你是如何解决的?

  • ……

面试高频,一步一步解决OOM、GC调优:

大师级GC调优:剖析高并发系统的垃圾回收优化实战

「轻盈」之旅:OOM故障重现与解决

Java

常⽤⼯具

Arthas

如果⾯试中聊到 Arthas 的话,⾯试官很可能会继续追问你 Arthas 的底层实现原理。

MAT

JDK⾃带⼯具

基础

不规范的枚举类代码引发的⼀场事故 - 阿⾥云开发者 - 2023

  • 现象:对象的状态属性(枚举类型)在插⼊数据库后丢失,变成了空⽩字符串。

  • 分析:通过 Arthas watch 命令发现 PayRequest 对象在转换过程中 status 属性丢失。

  • 原因:直接原因:枚举类 Status 提供了 setter ⽅法,违反了枚举使⽤规范。根本原因:第三⽅库 podam 在解析枚举类时,错误地通过反射调⽤了 setter ⽅法。

  • 建议:⾸要的是写代码还是要注意规范,最好本地装⼀些扫描⼯具,例如 sonar,发现⻛险⼀定要尽快按照建议修复。


⼀⾏ MD5 居然让⼩伙伴都回不了家! - 京东云开发者 - 2023

  • 现象:测试环境中,⾸次请求超时,后续请求迅速返回。

  • 分析:使⽤ Arthas trace 命令查看⽅法耗时。

  • 原因:Hutool ⾃带的 MD5 算法使⽤存在问题(第⼀次加载很慢),使⽤ Google 提供的MD5 算法成功解决问题。

  • 建议:使⽤第三⽅包的时候要⼩⼼,尤其是没有⼤公司背书的第三⽅包。


多线程




  • 详解⼀次由读写锁引起的内存泄漏 - Coder 的技术之路 -2021:为了实现 LRU 功能,通过重写 LinkedHashMap get() ⽅法,在 get 之后,将当前节点移动到链表最后。因此,即使是 get 操作,其实际依然是⼀个写操作。所以,不应该使⽤读写锁,⽽应该使⽤互斥锁。还是更推荐的还是使⽤分布式缓存或者 Guava 缓存、Caffeine 这些⽐较完善的本地缓存的实现。

常⻅⽣产问题

CPU使⽤率⾼(重要)

相关⾯试题:

  1. CPU100%,你是怎么处理的?
  2. 线上服务 CPU100% 问题,如何快速定位?
  3. CPU 占⽤情况如何分析?

解决 CPU 使⽤率⾼的常⽤⼯具:

  1. jvm ⾃带的⼯具 jstack:使⽤ top 命令定位⾼ CPU 占⽤线程,再使⽤ jstack 命令查看线程栈信息。

  2. 阿⾥开源的全能的故障诊断⼯具 Arthas(更推荐):

  • dashboard 命令查看 TOP N 线程, thread 命令查看堆栈信息。

  • 内部集成的⽕焰图⼯具 async-profiler


利⽤ jstack 解决线上服务 CPU 100% - HeapDump - 2021

  • 现象:钉钉告警:CPU 超过告警阈值,达 100%;客户反馈:系统登录失败,报 504 错误。

  • 分析:使⽤ top -Hp <进程ID> 定位⾼ CPU 占⽤线程,再使⽤ jstack <进程ID> > jstack.txt 查看线程栈信息

  • 建议:对于此类耗资源的操作,⼀定要做好相应的限制。⽐如可以限制请求量,控制最⼤分⻚⼤⼩,同时可以限制访问频率,⽐如同⼀⽤户⼀分钟内最多请求多少次。

  • 资料字节⾯试:CPU被打满/CPU100%,如何处理? - 技术⾃由圈


⽤ Arthas 解决线上正则表达式导致 CPU100%的问题 - 掘⾦ - 2023

  • 现象:⼀个服务出现了 cpu 达到 100%的问题。

  • 分析:使⽤ arthas 查看线程信息,输⼊ thread -n 10 ,列出 10 个占⽤ cpu 最⾼的线程堆栈信息。


不经意的两⾏代码把 CPU 使⽤率⼲到了 90%+ - HeapDump - 2023

现象:应⽤使⽤ schedulerx 执⾏定时任务,每⼩时执⾏⼀次,每次约 5 分钟,执⾏任务期间 CPU 使⽤率 90%+。

分析:Arthas 内部集成的⽕焰图⼯具 async-profiler ⽐较适⽤ CPU 使⽤率持续较⾼的场景。通过对热点⽕焰图的分析, NoSuchMethodException 异常相关代码占⽤了很多 CPU时间。为了更准确的定位相关业务代码,我们需要知道抛出 NoSuchMethodException 的线程栈,可以使⽤ Arthas stack,从线程栈我们可以知道在【哪个类哪个⽅法哪⾏】发出的调⽤。


OOM/内存泄露(重要)

相关⾯试题:

  1. 如果项⽬遇到了 OOM 问题,你会如何排查?
  2. 你遇到过 OOM 问题吗?最后怎么解决的?

解决 OOM/内存泄露的常⽤⼯具:

  1. JDK ⾃带的 VisualVM:使⽤ jmap 命令⽣成堆转储快照也就是 dump ⽂件,然后通过VisualVM 分析 dump ⽂件。

  2. MAT (Memory Analyzer Tool):MAT 也可以分析 dump ⽂件。

阿⾥云开发者发表过⼀篇三万字⻓⽂:JVM内存问题排查Cookbook - 2024,堪称应⽤内存问题排查保姆级指南。不过,这篇写的过于详细,实际⾯试中是需要介绍这么详细的,直接针对⾃⼰项⽬遇到的问题去介绍即可。


⼀次线上 OOM 问题分析 - 艾⼩仙 - 2023

  • 现象:线上某个服务有接⼝⾮常慢,通过监控链路查看发现,中间的 GAP 时间⾮常⼤,实际接⼝并没有消耗很多时间,并且在那段时间⾥有很多这样的请求。

  • 分析:使⽤ JDK ⾃带的 jvisualvm 分析 dump ⽂件。

  • 建议:对于 SQL 语句,如果监测到没有 where 条件的全表查询应该默认增加⼀个合适的 limit 作为限制,防⽌这种问题拖垮整个系统

  • 资料:实战案例:记⼀次 dump ⽂件分析历程转载 - HeapDump - 2022


⽣产事故-记⼀次特殊的 OOM 排查 - 程语有云 - 2023

  • 现象:⽹络没有问题的情况下,系统某开放接⼝从 2023 年 3 ⽉ 10 ⽇ 14 时许开始⽆法访问和使⽤。

  • 临时解决办法:紧急回滚⾄上⼀稳定版本。

  • 分析:使⽤ MAT (Memory Analyzer Tool)⼯具分析 dump ⽂件。

  • 建议:正常情况下, -Xmn 参数(控制 Young 区的⼤⼩)总是应当⼩于 -Xmx 参数(控制堆内存的最⼤⼤⼩),否则就会触发 OOM 错误。

  • 资料最重要的 JVM 参数总结 - JavaGuide - 2023


⼀次⼤量 JVM Native 内存泄露的排查分析(64M 问题) - 掘⾦ - 2022


GC问题

记⼀次 CMS GC 耗时 46.6 秒的 排查与解决过程 - 掘⾦ - 2023

  • 现象:HTTP 接⼝请求延时过⾼。

  • 分析:使⽤ MAT (Memory Analyzer Tool) ⼯具分析 dump ⽂件(⽼套路了)。

  • 建议:监控⼯具⾮常重要,SQL 语句的编写需要谨慎。


YGC 问题排查,⼜让我涨姿势了! - IT ⼈的职场进阶 - 2021

  • 现象:⼴告服务在新版本上线后,收到了⼤量的服务超时告警。

  • 分析:使⽤ MAT (Memory Analyzer Tool) ⼯具分析 dump ⽂件。

  • 建议:学会 YGC(Young GC) 问题的排查思路,掌握 YGC 的相关知识点。


听说 JVM 性能优化很难?今天我⼩试了⼀把! - 陈树义 - 2021

通过观察 GC 频率和停顿时间,来进⾏ JVM 内存空间调整,使其达到最合理的状态。调整过程记得⼩步快跑,避免内存剧烈波动影响线上服务。 这其实是最为简单的⼀种 JVM 性能调优⽅式了,可以算是粗调吧。


你们要的线上 GC 问题案例来啦 - 编了个程 - 2021

案例 1:使⽤ guava cache 的时候,没有设置最⼤缓存数量和弱引⽤,导致频繁触发Young GC

案例 2: 对于⼀个查询和排序分⻚的 SQL,同时这个 SQL 需要 join 多张表,在分库分表下,直接调⽤ SQL 性能很差。于是,查单表,再在内存排序分⻚,⽤了⼀个 List 来保存数据,⽽有些数据量⼤,造成了这个现象。


Java 中 9 种常⻅的 CMS GC 问题分析与解决 - 美团技术团 - 2020

这篇⽂章共 2w+ 字,详细介绍了 GC 基础,总结了 CMS GC 的⼀些常⻅问题分析与解决办法。


数据库

MySQL

死锁问题(重要)

⼿把⼿教你分析解决 MySQL 死锁问题 - 后端元宇宙 - 2024

⽣产环境中,MySQL 死锁还是挺常⻅的,⾯试被提问的概率也较⼤。这篇⽂章详细介绍了

MySQL 死锁问题该如何排查和解决。

解决 MySQL 死锁问题的思路:

  1. 使⽤ show engine innodb status; 查看死锁⽇志,然后分析死锁⽇志。
  2. 如果第⼀种⽅式⽆法解决死锁问题,可以通过 binlog ⽇志获取锁事务所执⾏的全部SQL。有了具体 SQL 语句,就能进⾏具体的锁冲突分析了。

类似的⽂章:


时区问题

⼀个诡异的 MySQL 查询超时问题,居然隐藏着存在了两年的 BUG - CoderW 喜欢写博客 -2021

  1. 时区没对上 :SQL ⽇志记录⾥⾯的时区都是标准时区,任务执⾏的时候是北京时间,标准时区和北京时区是差了 8 个⼩时。

  2. 底层在取时间区间时,调了⼀个 RPC 接⼝,这个接⼝预期返回的时间区间只有⼏天,结果返回了七个⽉的时间区间。查询的⽇期区间从 2020 年 9 ⽉到 2021 年 4 ⽉,时间跨度7 个⽉。MySQL 成本计算的时候认为区间太⼤,⾛索引还不如直接扫描全表,最终没有⾛索引扫描了 1800W 条数据。


慢查询

慢查询引发的⻋祸现场,案例分析! - ⽉伴⻜⻥ - 2021

分享了⼏个导致慢查询的案例。


隐式转换

⼀个 MySQL 隐式转换的坑,差点把服务器整崩溃了 - 古时的⻛筝 - 2022

我们在平时的开发过程中,尽量要避免隐式转换,因为⼀旦发⽣隐式转换除了会降低性能

外, 还有很⼤可能会出现不期望的结果。


事务隔离级别错误

MySQL 可重复读,差点就让我背上了⼀个 P0 事故! - 楼下⼩⿊哥 - 2020

真实事件,交易系统,p0 事故:余额多扣!


Redis

⼀次 Redis 主从切换导致的数据丢失与陷⼊只读状态故障

Redis 主从切换导致的数据丢失与集群陷⼊只读状态故障。事故最后的原因很简单,运⾏配置和静态配置不⼀致导致的。修改配置时,切记分析清楚,到底是要永久性的,还是⼀次性的。


Redis——由分布式锁造成的重⼤事故 - 浪漫先⽣ - 2020

分布式锁使⽤不当导致超卖。


消息队列

Kafka

⼀次 Kafka 消息堆积问题排查 - 张乘辉 - 2020

项⽬中某 Kafka 消息组消费特别慢,有时候在 kafka-manager 控制台看到有些消费者已被踢出消费组。该消费组在短时间内重平衡了 600 多次。

RabbitMQ

RabbitMQ 消息延迟和堆积实战 - 菜农⽈ - 2021

消息延迟 :TTL + 死信队列(⽐较麻烦)、RabbitMQ 延迟队列插件(更简单,相关阅读:[RabbitMQ 延迟插件的使⽤](https://mp.weixin.qq.com/s/rFN_MkEIyeUbmttwdN-YGw)

消息堆积解决:增加消费者、多线程、扩⼤队列的容量、惰性队列(更灵活但消息的时效性降低,接收到消息后直接存⼊磁盘⽽⾮内存,⽀持百万级消息的存储)

⽹络

万字⻓⽂让你掌握⽹络问题排查技巧! - 安琪拉的博客 - 2021

⽹络问题很考验⼯程师解决问题的功⼒,这类问题需要对 TCP 的原理,抓包⼯具有⽐较深⼊的理解和运⽤,这篇⽂章以实战⻆度为你讲述了⽹络问题的排查思路,⾮常值得⼀看!