美文网首页
记录一次线上服务接口偶现超时问题定位(内存问题)

记录一次线上服务接口偶现超时问题定位(内存问题)

作者: Yves_Chen | 来源:发表于2019-02-26 17:22 被阅读0次

    发现问题:上层服务A任务失败触发告警,排查是因为调用服务B时接口偶现time out。
    登录服务B定位:
    首先确定网络无异常。
    然后查看了下上层服务A报超时的请求,服务B确实产生了访问日志,怀疑是服务B内部问题。
    Top查看了下CPU使用情况,发现CPU使用率较低,但是每隔几秒会跑到300%以上(4核),业务上没有这种间隔几秒执行的后台任务,怀疑是GC异常了。
    用jstat -gc *** 5000 10查看GC情况,吓了一跳。每隔5秒打印一次GC,FGC在不断增长,几乎每5秒FGC要增长1~2次,每次花费2秒。(公司内网无法上传图片,改文字描述。。。)
    用jmap -histo:live看了下堆内的对象占用情况,发现业务对象占用很低,绝大部分是hibernate的内部对象。
    用jmap将堆导出,然后重启了服务,观察服务暂时正常,然后用MAT打开堆文件分析内存泄漏情况:
    One instance of "org.hibernate.internal.SessionFactoryImpl" loaded by "org.apache.catalina.loader.WebappClassLoader @ 0x70012b8a0" occupies 2,683,463,880 (95.68%) bytes. The memory is accumulated in one instance of "org.hibernate.internal.util.collections.BoundedConcurrentHashMap$Segment[]" loaded by "org.apache.catalina.loader.WebappClassLoader @ 0x70012b8a0".
    发现SessionFactoryImpl下整个引用链占用了对95.68%的空间,往下跟踪了一下,发现空间是被org.hibernate.engine.query.spi.QueryPlanCache占用。
    查了下资料,QueryPlanCache占用多大,它基本上归结为IN子句中具有可变数量的值,而Hibernate试图缓存这些查询计划。如: select t from Thing t where t.id in (?)。Hibernate缓存这些解析的HQL查询。如果in子句后面跟不同数量或数值,都会增加一条缓存。业务上确实存在in后面带了大量子句的场景。
    先配置
    <property
    name="hibernate.query.plan_cache_max_size"
    value="2048"
    />
    <property
    name="hibernate.query.plan_parameter_metadata_max_size"
    value="128"
    />
    暂时规避问题。
    PS:奇怪为什么这里做缓存不用WeakReference或SoftReference?

    相关文章

      网友评论

          本文标题:记录一次线上服务接口偶现超时问题定位(内存问题)

          本文链接:https://www.haomeiwen.com/subject/smgayqtx.html