• RabbitMQ消费者消失与 java OOM


    原因: 下午先是收到钉钉告警有一个消费者系统任务积压, 当时以为就是有范围上量没有当回事,后来客服群开始反馈说有客户的数据没有生成。这个时候查看mq的后台,发现任务堆积数量还是很多。 这个时候登录一台消费者系统查看日志,发现OOM

    复制代码
    [2022-07-09 16:40:34.640] [ERROR] [org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-9] [org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.run:1251] 
    - Consumer thread error, thread abort. java.lang.OutOfMemoryError: Java heap space at java.lang.String.(String.java:662) at com.alibaba.fastjson.serializer.SerializeWriter.toString(SerializeWriter.java:503) at com.alibaba.fastjson.JSON.toJSONString(JSON.java:760) at com.alibaba.fastjson.JSON.toJSONString(JSON.java:696) at com.alibaba.fastjson.JSON.toJSONString(JSON.java:661) at sun.reflect.GeneratedMethodAccessor169.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:171) at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:120) at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:50) at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:211) at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandlerAndProcessResult(MessagingMessageListenerAdapter.java:143) at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:132) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1569) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1488) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer$$Lambda$976.0000000000000000.invokeListener(Unknown Source) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1476) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1467) at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1411) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:958) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:908) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:81) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1279) at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1185) at java.lang.Thread.run(Thread.java:819)
    复制代码

     

    先看第一个重点:Consumer thread error, thread abort.

    从错误中就可以明显看出来,问题的原因:是因为消费线程在执行的过程中,出现内存溢出,导致线程和MQ断开链接。最终导致消息堆积的出现,只要解决内存溢出的问题即可。

     

    OOM的问题排查

    线程OOM后打印的文件我们用MAT工具排查(公司使用的JDK是openJ9)

     

     从图像上很明显看出那里占用的大部分内存, 有一个超级大的map,继续分析看看map里的内容是谁。

     

     根据类路径去代码中查询为什么会生成这么多对象。

     

    首先找到在那里使用了这个类

     

     

     

     

    这是logback的类,当时使用这个做日志的打印是想打印这个数据的业务流转日志。 单独输出到一个文件中,方便问题的排查。

    知道这个类以后再深入查看一下map数据怎么来的

     

     

     

     

    从这里看到使用了final的map并且在调用write的时候获取helper是调用的computeIfAbsent。 

    computeIfAbsent()
    1、首先会判断map中是否有对应的Key;
    2.如果没有对应的Key,则会创建一个满足Value类型的数据结构放到Value的位置中;
    3.如果有对应的Key,则会操作该Key对应的Value.

     在这里就怀疑是不是因为我程序中每次传递的mapper都是新new的。然后就找我调用的方法。

     

     

     

    这个类是我用来logback扩展json字段转换用的。  我在构造JsonGenerator的时候每次都是新new ObjectMapper(), 所以会导致map每次比较的时候发现传递的值是不相同的,会new 一个新的放到Map中。最终导致map变的异常大。

     

    修改很简单

     

     

  • 相关阅读:
    CUDA Programming Model--CUDA编程模型
    02c++呵呵老师【官方案例FloatingActor】
    C语言每日一题(34)链表的回文结构
    一种通用的业务监控触发方案设计
    SAP SMARTFORMS 文本框显示默认浏览器
    什么是Ajax?全面了解
    【算法之路】高精度算法(实现加减乘除)
    禅道安装(非docker 版本)(一键部署版)
    Share| Membership in the American Society of Professionals in P
    rosbag保存 pcd和image
  • 原文地址:https://www.cnblogs.com/technologykai/p/16493478.html