首页 > 其他分享 >一次线上OOM问题分析

一次线上OOM问题分析

时间:2023-02-28 20:36:36浏览次数:31  
标签:分析 java dump OOM 代码 问题 XX 线上

现象

线上某个服务有接口非常慢,通过监控链路查看发现,中间的 GAP 时间非常大,实际接口并没有消耗很多时间,并且在那段时间里有很多这样的请求。

原因分析

先从监控链路分析了一波,发现请求是已经打到服务上了,处理之前不知道为什么等了 3s,猜测是不是机器当时负载太大了,通过 QPS 监控查看发现,在接口慢的时候 CPU 突然增高,同时也频繁的 GC ,并且时间很长,但是请求量并不大,并且这台机器很快就因为 Heap满了而被下掉了。

去看了下日志,果然有 OOM 的报错,但是从报错信息上并没办法找到 Root Cause。

system error: org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.OutOfMemoryError: Java heap space   at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1055)   at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)   at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)   at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)   at javax.servlet.http.HttpServlet.service(HttpServlet.java:681) 

另外开发同学提供了线索,在发生问题的时候在跑一个大批量的一次性 JOB,怀疑是不是这个 JOB 导致的,马上把 JOB 代码拉下来分析了下,JOB 做了分批处理,代码也没有发现什么问题。

虽然我们系统加了下面的 JVM 参数,但是由于容器部署的原因,这些文件在 pod 被 kill 掉之后没办法保留下来。

-XX:+HeapDumpOnOutOfMemoryError -XX:ErrorFile=/logs/oom_dump/xxx.log -XX:HeapDumpPath=/logs/oom_dump/xxx.hprof

这个现象是最近出现的,猜测是最近提交的代码导致的,于是去分析了最近提交的所有代码,很不幸的都没有发现问题。。。

在分析代码的过程中,该服务又无规律的出现了两次 OOM,只好联系运维同学优先给这个服务加了 EFS (Amazon 文件系统)等待下次出现能抓住这个问题。

刚挂载完 EFS,很幸运的就碰到了系统出现 OOM 的问题。

dump 出来的文件足有 4.8G,话不多说祭出 jvisualvm 进行分析,分析工具都被这个dump文件给搞挂了也报了个java.lang.OutOfMemoryError: Java heap space,加载成功之后就给出了导致OOM的线程。

找到了具体报错的代码行号,翻一下业务代码,竟然是一个查询数据库的count操作,这能有啥问题?

仔细看了下里面有个foreach遍历userId的操作,难道这个userId的数组非常大?

找到class按照大小排序,占用最多的是一个 byte 数组,有 1.07G,char 数组也有1.03G,byte 数组都是数字,直接查看 char 数组吧,点进去查看具体内容,果然是那条count语句,一条 SQL 1.03G 难以想象。。。

这个userId的数据完全是外部传过来的,并没有做什么操作,从监控上看,这个入参有 64M,马上联系对应系统排查为啥会传这么多用户过来查询,经过一番排查确认他们有个bug,会把所有用户都发过来查询。。。到此问题排查清楚。

解决方案

对方系统控制传入userId的数量,我们自己的系统也对userId做一个限制,问题排查过程比较困难,修改方案总是那么的简单。

别急,还有一个

看到这个问题,就想起之前我们还有一个同样类似的问题导致的故障。

也是突然收到很多告警,还有机器 down 机的告警,打开 CAT 监控看的时候,发现内存已经被打满了。

操作和上面的是一样的,拿到 dump 文件之后进行分析,不过这是一个漫长的过程,因为 down了好几台机器,最大的文件有12GB。

通过 MAT 分析 dump 文件发现有几个巨大的 String(熟悉的味道,熟悉的配方)。

接下来就是早具体的代码位置了,去查看了下日志,这台机器已经触发自我保护机制了,把代码的具体位置带了出来。

经过分析代码发现,代码中的逻辑是查询 TIDB(是有同步延迟的),发现在极端情况下会出现将用户表全部数据加载到内存中的现象。

于是找 DBA 拉取了对应时间段 TIDB 的慢查询,果然命中了。

总结

面对 OOM 问题如果代码不是有明显的问题,下面几个JVM参数相当有用,尤其是在容器化之后。

-XX:+HeapDumpOnOutOfMemoryError -XX:ErrorFile=/logs/oom_dump/xxx.log -XX:HeapDumpPath=/logs/oom_dump/xxx.hprof

另外提一个参数也很有用,正常来说如果程序出现 OOM 之后,就是有代码存在内存泄漏的风险,这个时候即使能对外提供服务,其实也是有风险的,可能造成更多的请求有问题,所以该参数非常有必要,可以让 K8S 快速的再拉起来一个实例。

-XX:+ExitOnOutOfMemoryError

另外,针对这两个非常类似的问题,对于 SQL 语句,如果监测到没有where条件的全表查询应该默认增加一个合适的limit作为限制,防止这种问题拖垮整个系统。

标签:分析,java,dump,OOM,代码,问题,XX,线上
From: https://www.cnblogs.com/ilovejaney/p/17165861.html

相关文章

  • 深入分析MobileAI图像超分最佳方案:ABPN
    前言 本文设计一种8-bit量化版高效网络并将其部署到移动端,旨在构建一种实时量化模型用于真实场景(比如实时视频超分)。本文转载自AIWalker来源|HappyAIWalker欢迎关......
  • Apache HttpClient使用和源码分析
    在上文中分析了HttpURLConnection的用法,功能还是比较简单的,没有什么封装接下来看看ApacheHttpClient是如何封装httpClient的目录组成请求代码代码分析自定义拦截器和处......
  • JS混淆解密技术研究与案例分析
    引言在现代互联网的世界中,JavaScript(JS)已成为最为流行和广泛使用的编程语言之一。JS的开发人员使用它来构建各种Web应用程序,包括网站、应用和游戏等。然而,随着JS应......
  • MySQL 性能优化浅析及线上案例
    作者:京东健康孟飞1、数据库性能优化的意义业务发展初期,数据库中量一般都不高,也不太容易出一些性能问题或者出的问题也不大,但是当数据库的量级达到一定规模之后,如果缺失有......
  • HttpURLConnection使用分析
    在项目中遇到各种版本的httpClient,所以想了解一下httpClient的实现首先查看的是JDK1.1中自带的HttpURLConnection,看一下最初的设计是怎么样的代码分析使用HttpURLConnec......
  • FFplay音频滤镜分析
    音频流的滤镜是通过 ​​configure_audio_filters()​​​ 函数来创建的,因为 ​​ffplay​​​ 为了代码的通用性,即便命令行参数不使用滤镜,​​AVFrame​​ 也会过一......
  • 内存不足时Linux 内核自动触发OOM-killer
    问题产生:作者最近在搭建Hadoop+Hive集群时,将NameNode、DataNode、Rm全部部署到一台物理机上,查询量较大时连接挂掉。问题定位:使用JPS命令查看Metastore服务正常运行,hive2......
  • 1.4 算法和算法分析
    1.4算法和算法分析算法定义对特定问题求解方法和步骤的一种描述,它是指令的有限序列。其中每个指令的表示一个或多个操作。简而言之,算法就是解决问题的方法和步骤。......
  • 算法和算法分析2
    对于同一个问题,可以有许多不同的算法。究竟如何来评价这些算法的优劣程度呢?算法分析的目的是看算法实际是否可行,并在同一问题存在多的算法时可进行性能上的比较,以便于从中......
  • 10条命令1分钟,快速分析Linux性能问题!
    秘籍:10条命令1分钟,快速分析Linux性能问题!如果某个Linux有性能问题,你登录之后来排查,第一分钟内你会使用哪些命令做那些方面的排查?在Netflix,我们在云端有大量的EC2实......