• 数据库连接池配置错误导致OOM


    一、背景介绍:

       运行在k8s集群中负责支付业务一个服务,运营一段时间就会被k8s kill,然后重启, 通过查看k8s 的event发现系统达到了memory到达了上限被集群kill调。

       服务配置:jdk:1.8、堆内存:-Xmx800m -Xms800m 设置为800M,  k8s的memory.limit设置为1G。 

    二、排查问题:

      1.初步分析: 由于系统的请求量不大,所以设置的堆内存足够了,所以可以排除堆内存设置过小原因。同时由于服务被kill的原因是因为物理内存占用过大。所以怀疑是堆外内存溢出

       jvm内存结构分为:堆内存(新生代、老年代), 堆外内存(线程栈、元空间、直接内存)

      2.排查:

        2.1 gc状态分析:jstat -gcutil pid 5s

        结果:各区域的占用情况,gc情况无明显异常

        2.2 堆dump: jmap -dump:format=b,file=heap.hprof  pid, 使用mat分析如下

     

      很明显 com.mysql.jdbc.NonRegisteringDriver占用堆内存的33%。其中java.util.concurrent.ConcurrentHashMap$Node[] 存在内存泄漏的可能。

    ConcurrentHashMap<ConnectionPhantomReference, ConnectionPhantomReference> connectionPhantomRefs  保存mysql connection的虚引用。
    当 mysql connection被释放后,虚引用的refQueue中会收到释放的connection。 定时清理线程会取出refQueue中保存的connection,然后将connection从 connectionPhantomRefs中清除。

      当查看详细情况发现: connectionPhantomRefs 保存的连接个数600多个,而mysql的tomcat的连接池最大设置的max-active=100, 

     

     这说明了两个问题:

    •  1. 有大部分的连接池没有被回收
    •  2. 最大连接数max-active:100,而实际生成的却远远大于max-active

    2.3 连接池配置分析

       根据2.2中堆dump的情况发现了两个问题:

    • (1) 有大部分的连接池没有被回收
    • (2)最大连接数max-active:100,而实际生成的却远远大于max-active,

      关于问题(1):通过jstat -gcutil pid 5s发现jvm old区占用50%,一直没有FGC。 通过jcmd GC.run手动gc后,再次dump发现om.mysql.jdbc.NonRegisteringDriver保存的连接数目减少了

      关于问题(2):  通过排查,发现tomcat连接池设置的最大生命周期 max-age:60000, 即连接创建一分钟后就会被销毁。 

    三、解决问题:

      1. 增加连接池超时时间,超时时间稍微小于mysql的waitTimeout即可

      2. jvm迟迟没有fgc导致连接池中连接没有释放,可以稍微调小堆内存

      3. 回归到最开始的疑问,为什么会是堆外内存溢出呢? 通过堆外内存几个区域的分析,发现其中大量的MysqlStatement Cancellation Timer:

          mysql每个连接一个超时检测线程用于检测sql语句是否超时,mysql的连接没有释放导致线程也未释放。 而线程栈占用默认大小为1m,所以导致了堆外内存溢出

      

  • 相关阅读:
    新萝卜家园GHOST WIN7系统32,64位极速装机特别版
    BiliBili 第三方 Android 客户端应用源码
    高仿饿了么应用项目源码
    12306火车票订票项目源码
    美女的秘密项目源码
    漫画阅读应用源码
    高仿美团应用客户端布局源码
    Unix时间戳 和 NSDate 的转换
    NSJSONSerialization-JSON数据与NSDictionary和NSArray之间的转化
    ReactiveCocoa入门教程——第一部分
  • 原文地址:https://www.cnblogs.com/mxmbk/p/13220594.html
Copyright © 2020-2023  润新知