Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >记一次 RabbitMQ 消费者莫名消失问题的排查

记一次 RabbitMQ 消费者莫名消失问题的排查

作者头像
青石路
发布于 2024-09-24 05:08:51
发布于 2024-09-24 05:08:51
31100
代码可运行
举报
文章被收录于专栏:开发技术开发技术
运行总次数:0
代码可运行

问题回顾

某天下午,生产监控告警:消息积压,队列 xxx 消息数超过 100;我第一时间想到的是应用服务是不是停了,但应用服务存活监控又没有告警,但我还是找值班运维同事帮忙确认了下,确认结果是服务的 6 个节点都是存活的,然后我又让运维确认了下队列的消费者情况,结果发现消费者列表中只有 2 个节点的消费者,其他 4 个节点的消费者不见了,所以消息消费不过来,导致了消息积压!

所以问题来了

那 4 个节点的注册的消费者为何消失?

但当务之急是解决消息积压的问题,所以让运维重启那 4 个节点的服务,消费者重新注册上,消息得以快速消费,消息积压告警得以恢复

生产问题虽暂时得以解决,但未找到根因,还是存在复发风险;下面就请大家跟随我的脚本,来看看我是如何排查的

问题排查

直接查 ERROR 级别的日志,很容易就能就找到了关键日志

Consumer thread error, thread abort.

以及异常堆栈

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
	at java.lang.StringCoding$StringEncoder.encode(StringCoding.java:300)
	at java.lang.StringCoding.encode(StringCoding.java:344)
	at java.lang.String.getBytes(String.java:918)
    ...

Consumer thread error, thread abort 大家能看懂吧,就是字面意思

消费者线程错误,线程中止

消费者线程就是我们前面提到的队列消费者,一个队列消费者就是一个消费者线程,消费者线程中止那就意味着队列消费者中止,也就对应文章标题中的 消费者消失;是不是离真相越来越近了?

OutOfMemoryError 是不是很熟悉,内存溢出嘛

OutOfMemoryError 表示 Java 虚拟机在堆内存中没有足够的空间来分配对象

问你们一个问题:OOM 一定会导致 JVM 退出吗,这个问题你们先思考,后面答案会揭晓

回到正题,从关键日志以及异常堆栈,我们是不是可以得出以下推测

OOM 会导致消费者线程中止

有了推测,那就去验证呗;我先给大家模拟下案例,基于 SpringBootpom.xml 关键依赖

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

配置文件 application.yml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
server:
  port: 8088
spring:
  rabbitmq:
    host: 192.168.2.118
    port: 5672
    username: admin
    password: admin
    virtual-host: /
    listener:
      simple:
        acknowledge-mode: manual #设置确认模式手工确认
        concurrency: 3 #消费者个数,线程个数
        prefetch: 1

RabbitMQ 配置 TaskRabbitConfig.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.qsl.rabbit.config;

import com.qsl.rabbit.constant.Constant;
import com.qsl.rabbit.listener.TaskMessageListener;
import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author: 青石路
 */
@Configuration
public class TaskRabbitConfig {

    @Value("${spring.rabbitmq.listener.simple.concurrency:3}")
    private int concurrency;
    @Value("${spring.rabbitmq.listener.simple.prefetch:1}")
    private int prefetch;

    @Bean
    public DirectExchange taskExchange() {
        return new DirectExchange(Constant.TASK_EXCHANGE, true, false);
    }

    @Bean
    public Queue taskQueue() {
        return new Queue(Constant.TASK_QUEUE, true, false, false);
    }

    @Bean
    public Binding bindingTaskQueue() {
        return BindingBuilder.bind(taskQueue()).to(taskExchange()).with(Constant.TASK_QUEUE);
    }

    @Bean
    public SimpleMessageListenerContainer taskMessageListenerContainer(ConnectionFactory connectionFactory) {

        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        //设置确认模式手工确认
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        container.setQueueNames(Constant.TASK_QUEUE);
        //消费者个数,线程个数
        container.setConcurrentConsumers(concurrency);
        //设置预处理个数
        container.setPrefetchCount(prefetch);

        container.setMessageListener(new TaskMessageListener());
        return container;
    }
}

消息监听器 TaskMessageListener.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @author: 青石路
 */
@Slf4j
public class TaskMessageListener implements ChannelAwareMessageListener {

    @Override
    public void onMessage(Message message, Channel channel) {
        String content = new String(message.getBody(), StandardCharsets.UTF_8);
        log.info("消费者接收到消息:{}", content);
        handleTask(content);
        try {
            // 手动ACK
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            log.error("消息确认失败,异常:", e);
        }
    }

    private void handleTask(String message) {
        try {
            // 业务处理
            log.info("处理任务:{}", message);
            log.info("任务处理完成");
        } catch (Exception e) {
            log.error("处理任务失败,异常:", e);
        }
    }
}

业务处理的时候进行 Exception 捕获,并且手动确认消息,我相信你们平时都是这么用的,这难道有什么问题?我调整下 handleTask 方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 业务处理
 * @param message 消息内容
 * @author: 青石路
 */
private void handleTask(String message) {
    try {
        // 业务处理
        log.info("处理任务:{}", message);
        int i = 3 / (message.length() % 10);
        if (i == 1) {
            throw new OutOfMemoryError("模拟内存溢出");
        }
        log.info("任务处理结果:{}", i);
    } catch (Exception e) {
        log.error("处理任务失败,异常:", e);
    }
}

启动服务后,队列消费者情况如下

服务启动队列消费者情况
服务启动队列消费者情况

发送消息 a,日志输出如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2024-09-22 20:15:55|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|20|消费者接收到消息:a
2024-09-22 20:15:55|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|37|处理任务:a
2024-09-22 20:15:55|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|42|任务处理结果:3

相当于业务正常处理;我们再发送消息 abcdefghij,日志输出如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2024-09-22 20:17:45|taskMessageListenerContainer-3|com.qsl.rabbit.listener.TaskMessageListener|INFO|20|消费者接收到消息:abcdefghij
2024-09-22 20:17:45|taskMessageListenerContainer-3|com.qsl.rabbit.listener.TaskMessageListener|INFO|37|处理任务:abcdefghij
2024-09-22 20:17:45|taskMessageListenerContainer-3|com.qsl.rabbit.listener.TaskMessageListener|ERROR|44|处理任务失败,异常:
java.lang.ArithmeticException: / by zero
	at com.qsl.rabbit.listener.TaskMessageListener.handleTask(TaskMessageListener.java:38)
	at com.qsl.rabbit.listener.TaskMessageListener.onMessage(TaskMessageListener.java:21)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1591)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1510)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1498)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1489)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1433)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:975)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:921)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1296)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1202)
	at java.lang.Thread.run(Thread.java:748)

被除数为 0,出现 ArithmeticException

ArithmeticException
ArithmeticException

相当于业务处理出现了 Exception,而我们进行了 catch,所以日志打印也符合我们的代码逻辑,也不会对消费者线程造成影响,队列消费者还是最初的那 3 个

还是那三个消费者
还是那三个消费者

我们发送消息 ab,日志输出如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2024-09-22 20:36:31|taskMessageListenerContainer-1|com.qsl.rabbit.listener.TaskMessageListener|INFO|20|消费者接收到消息:ab
2024-09-22 20:36:31|taskMessageListenerContainer-1|com.qsl.rabbit.listener.TaskMessageListener|INFO|37|处理任务:ab
2024-09-22 20:36:31|taskMessageListenerContainer-1|org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer|ERROR|1268|Consumer thread error, thread abort.
java.lang.OutOfMemoryError: 模拟内存溢出
	at com.qsl.rabbit.listener.TaskMessageListener.handleTask(TaskMessageListener.java:40)
	at com.qsl.rabbit.listener.TaskMessageListener.onMessage(TaskMessageListener.java:21)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1591)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1510)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1498)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1489)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1433)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:975)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:921)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1296)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1202)
	at java.lang.Thread.run(Thread.java:748)
2024-09-22 20:36:31|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|20|消费者接收到消息:ab
2024-09-22 20:36:31|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|37|处理任务:ab
2024-09-22 20:36:31|taskMessageListenerContainer-2|org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer|ERROR|1268|Consumer thread error, thread abort.
java.lang.OutOfMemoryError: 模拟内存溢出
	at com.qsl.rabbit.listener.TaskMessageListener.handleTask(TaskMessageListener.java:40)
	at com.qsl.rabbit.listener.TaskMessageListener.onMessage(TaskMessageListener.java:21)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1591)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1510)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1498)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1489)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1433)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:975)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:921)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1296)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1202)
	at java.lang.Thread.run(Thread.java:748)
2024-09-22 20:36:31|taskMessageListenerContainer-3|com.qsl.rabbit.listener.TaskMessageListener|INFO|20|消费者接收到消息:ab
2024-09-22 20:36:31|taskMessageListenerContainer-3|com.qsl.rabbit.listener.TaskMessageListener|INFO|37|处理任务:ab
2024-09-22 20:36:31|taskMessageListenerContainer-3|org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer|ERROR|1268|Consumer thread error, thread abort.
java.lang.OutOfMemoryError: 模拟内存溢出
	at com.qsl.rabbit.listener.TaskMessageListener.handleTask(TaskMessageListener.java:40)
	at com.qsl.rabbit.listener.TaskMessageListener.onMessage(TaskMessageListener.java:21)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1591)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1510)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1498)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1489)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1433)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:975)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:921)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1296)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1202)
	at java.lang.Thread.run(Thread.java:748)
2024-09-22 20:36:31|taskMessageListenerContainer-1|org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer|ERROR|1415|Stopping container from aborted consumer
2024-09-22 20:36:31|taskMessageListenerContainer-1|org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer|INFO|646|Waiting for workers to finish.
2024-09-22 20:36:31|taskMessageListenerContainer-1|org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer|INFO|649|Successfully waited for workers to finish.

可以看到,除了我们的业务日志,还有 spring 的日志;从日志可以看出,消息一共被消费了 3 次,但无一例外,都消费失败了,每次失败日志都包括

Consumer thread error, thread abort. Stopping container from aborted consumer

我们再去看下队列消费者情况

消费者无了
消费者无了

我们把这个流程捋一捋

消费者线程 taskMessageListenerContainer-1 收到消息,业务处理的时候 OOM 了,Spring 中止该线程,消息未被手动确认,回到队列等待被消费 消费者线程 taskMessageListenerContainer-2 收到消息,业务处理的时候又 OOM,Spring 中止该线程,消息未被手动确认,回到队列等待被消费 消费者线程 taskMessageListenerContainer-3 收到消息,业务处理的时候扔 OOM,Spring 中止该线程,消息未被手动确认,回到队列等待被消费

全部的 3 个消费者线程都被 Spring 中止了,对应的 3 个队列消费者也就都无了,消息最终回到队列,等待下一个就绪的消费者消费

我们不是 catch 了 Exception 吗,为什么 OutOfMemoryError 还是向上抛给了 Spring ?

OutOfMemoryError
OutOfMemoryError

OutOfMemoryError 是 Error,并不是 Exception,所以我们的代码并不会捕获 OutOfMemoryError,继续往上抛给了 Spring,而

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.AsyncMessageProcessingConsumer#run

中有这么一段代码

Spring对Error处理
Spring对Error处理

publishConsumerFailedEvent 发布一个消费者失败事件,事件处理器收到该事件后会中止该线程;这里就不展开讲了,后续我再写一篇源码,给你们好好介绍下 Spring 的中止逻辑

至此,OutOfMemoryError 会导致消费者线程中止,大家都清楚了吧;细心的小伙伴可能会有这样的疑问了

照理来说,生产中 6 个节点的消费者线程不应该都被中止吗,为什么还剩 2 个节点的消费者?

这 2 个节点内存比较充足,所以 JVM 的堆内存配置的比较大,它们的消费者线程在处理消息的时候,并不会 OOM;而当天正好是业务人员在进行历史大数据量处理,几轮操作下来,把那 4 个内存比较小的节点的消费者全干没了,只剩下那 2 个内存比较大的节点的消费者了

根因其实是 OutOfMemoryError,当前只知道是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
com.fasterxml.jackson.databind.ObjectMapper#writeValueAsString

这个方法导致的,具体原因还待进一步排查

问题处理

因为 OutOfMemoryError 的原因没找到,并且是在操作历史大数据量这种很少出现的场景中触发 OutOfMemoryError,也没有导致服务重启,所以暂定方式是将 ERROR 也捕获

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 业务处理
 * @param message 消息内容
 * @author: 青石路
 */
private void handleTask(String message) {
    try {
        // 业务处理
        log.info("处理任务:{}", message);
        int i = 3 / (message.length() % 10);
        if (i == 1) {
            throw new OutOfMemoryError("模拟内存溢出");
        }
        log.info("任务处理结果:{}", i);
    } catch (Exception | Error e) {
        log.error("处理任务失败,异常:", e);
    }
}

重新启动服务,继续消费队列中那条未被消费的消息 ab,此时日志输出如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2024-09-22 21:38:57|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|20|消费者接收到消息:ab
2024-09-22 21:38:57|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|INFO|37|处理任务:ab
2024-09-22 21:38:57|taskMessageListenerContainer-2|com.qsl.rabbit.listener.TaskMessageListener|ERROR|44|处理任务失败,异常:
java.lang.OutOfMemoryError: 模拟内存溢出
	at com.qsl.rabbit.listener.TaskMessageListener.handleTask(TaskMessageListener.java:40)
	at com.qsl.rabbit.listener.TaskMessageListener.onMessage(TaskMessageListener.java:21)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1591)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1510)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1498)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:1489)
	at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1433)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:975)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:921)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1600(SimpleMessageListenerContainer.java:83)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.mainLoop(SimpleMessageListenerContainer.java:1296)
	at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1202)
	at java.lang.Thread.run(Thread.java:748)
2024-09-22 21:38:57|main|com.qsl.rabbit.RabbitmqApplication|INFO|61|Started RabbitmqApplication in 1.045 seconds (JVM running for 1.515)

虽然业务处理仍然失败,但只有符合我们代码逻辑的错误日志输出,并没有 Spring 的错误日志,此时队列消费者情况如下

问题处理
问题处理

当然,这只是缓兵之计,最终解决方案还是要分析 OOM 的原因,然后对症下药

总结

  1. 示例代码:spring-boot-rabbitmq
  2. OOM 不一定会导致 JVM 退出,但是 SimpleMessageListenerContainer 会捕获它,然后中止当前线程,对应的队列消费者也就无了
啪,快乐没了
啪,快乐没了
  1. 业务代码 catch Error 虽说只是缓兵之计,但从健壮性考虑的话,也是一个不错的解决办法 但 OOM 的原因还得继续排查,然后对症下药,这才是最终解决之道
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-09-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
3个月挖到55个漏洞,这伙白帽获苹果超330万元的赏金
近日,一名安全研究者表示,苹果公司的企业网络在过去几个月一直面临严重的安全威胁,处于受到黑客攻击的危险中。黑客有可能窃取了其数百万用户的敏感数据,并在他们的手机和电脑上执行了恶意代码。
深度学习与Python
2020/10/23
6560
3个月挖到55个漏洞,这伙白帽获苹果超330万元的赏金
苹果的同行,能否喝到Vision Pro的热汤
写在前面:VR(Virtual Reality,虚拟现实)、AR(Augmented Reality,增强现实)、MR(混合现实)等相关概念众多,非行业人士真的分不清。在此文中,我们将与此相关的行业定义为元宇宙行业。
华尔街科技眼
2023/06/08
2320
写给开发者的 Vision Pro 评测:易上手,但 UI 设计不够“革命”
苹果为 Vision Pro 打造的 VisionOS 新平台在设计上大量借鉴了现有 3D 与 iOS 工具。但在开发者眼中,这一切是否足够有吸引力?
深度学习与Python
2023/08/09
3850
写给开发者的 Vision Pro 评测:易上手,但 UI 设计不够“革命”
从Quest3/Vision Pro浅淡“空间计算”
2023 年 6 月 6 日凌晨,苹果在 WWDC23 上发布了旗下首款 MR 产品 Apple Vision Pro,售价为 3499 美元。仅三个月后的 2023 年 9 月 28 日,Meta 在其召开的 Meta Connect 大会上发布了 Meta Quest 3 头显,售价 499 美元。二者都不约而同的强调 了自己在 MR(混合现实)方面的能力和表现,都希望自己可以将整个世界带入“空间计算”的时代。但和 Quest3 不同的是,Apple Vision Pro 直到 2024 年 2 月 2 日才正式在北美开售,如今各路评测视频都已经放出,笔者也购入了被大多数人誉为“Vision Pro 最佳平替”的 Meta Quest3,想借着自己实际的使用体验聊一聊“空间计算”这个全新的概念。喜欢的朋友不妨点个赞关注一下哦 😯
出其东门
2024/02/29
3270
从Quest3/Vision Pro浅淡“空间计算”
及时修复!苹果两大零日漏洞影响iPhone、iPad和Mac
近日,苹果公司发布紧急安全更新,此次更新修复了两个在攻击中被利用并影响 iPhone、iPad 和 Mac 设备的零日漏洞。据统计,自今年年初以来已修复的零日漏洞数量已达到 20 个。
FB客服
2023/12/03
4960
及时修复!苹果两大零日漏洞影响iPhone、iPad和Mac
网安大事记 | 2021年度漏洞利用事件汇总
网络时代,万物互联,人们在享受数字生活带来的福利时,背后隐藏的安全漏洞也正时刻构成威胁,只要技术是一把双刃剑,漏洞就将伴随信息技术的不断发展,与之相对应的,一些网络黑客对漏洞的利用技术也在提升,攻击事件变得越发频繁。
雨笋教育
2022/01/25
2.2K0
网安大事记 | 2021年度漏洞利用事件汇总
专属| Dell遭受黑客攻击
日前,戴尔发布公告称:“检测并瓦解了一场针对 Dell.com 的网络攻击,未经授权的攻击者试图窃取戴尔的客户信息,但仅限于姓名、电子邮件地址、以及散列(哈希)后的密码”。尽管未发现任何服务器上的客户信息被渗透的证据,但不排除有数据泄露的可能。戴尔建议客户重置所有密码,以防止客户信息的进一步泄露 ——“所有客户请通过多步身份验证流程,以重新获得对账户的访问权限”。
漏斗社区
2018/12/21
9560
专属| Dell遭受黑客攻击
苹果WWDC 2023发布会总结
今年的全球开发者大会没有让人失望。在今天的主题演讲中,苹果首次展示了备受期待的混合现实耳机,证实了过去几个月出现的许多谣言。
用户9283427
2023/06/07
6110
苹果WWDC 2023发布会总结
苹果曝严重安全漏洞,喜提热搜第一
据媒体报道,苹果公司在周三(8月17日)发布了两份安全报告,承认公司的智能手机iPhone、平板电脑iPad和iMac电脑等产品存在严重的安全漏洞。 公开信息查询显示,该漏洞报告时间为 2022年6月9日,漏洞编号分别是CVE-2022-32894和CVE-2022-32893,主要影响以下两部分: 内核:应用程序或许能够以内核权限执行任意代码。 Webkit:处理恶意制作的网页内容可能会导致任意代码执行。 这些漏洞一旦被利用,黑客可直接获得设备的管理权限。苹果也指出,该漏洞很大可能已经被利用,强烈督
FB客服
2023/03/30
4110
苹果曝严重安全漏洞,喜提热搜第一
漏洞一披露就被利用,LineageOS、Ghost 服务器遭黑客入侵
4月30日,安全公司 F-Secure 的研究人员披露了SaltStack两个高危漏洞CVE-2020-11651 和 CVE-2020-11652。而黑客行动迅速,很快就利用该漏洞对 LineageOS、Ghost 和DigiCert 的服务器发起了攻击。
FB客服
2020/05/14
6810
漏洞一披露就被利用,LineageOS、Ghost 服务器遭黑客入侵
黑客不讲武德,苹果好自为之
上周,在第三场秋季新品发布会上,作为开启 Apple silicon 时代的新操作系统,苹果正式推出了 macOS Big Sur。在功能上,Big Sur 明显“借鉴”了苹果自家 iOS 和 iPadOS 的特征,比如引入控制中心,包含 WiFi、蓝牙、屏幕亮度、声音等调节选项等等,可见 Big Sur 是苹果打通三大系统的一个重要手段。
深度学习与Python
2020/12/07
1.8K0
苹果Vision Pro拆解:内部细节全面曝光!
今年1月19日晚间,苹果的备受关注的首款MR产品Vision Pro正式在美国地区开启预售,虽然售价高达3499美元(约合人民币2.5万元)起,但依旧是订购火爆,18分钟左右就库存就已售罄。近日,已经有部分用户和机构已经拿到了Vision Pro。国外专业的拆解机构iFixit在昨日也率先带来了Vision Pro的全球首拆!
芯智讯
2024/02/06
4370
苹果Vision Pro拆解:内部细节全面曝光!
网络托管巨头百万数据外泄、超900万安卓设备感染木马|11月24日全球网络安全热点
网络托管巨头GoDaddy周一披露了一起数据泄露事件,导致共有120万活跃和非活跃客户的数据遭到未经授权的访问,这是自2018年以来曝光的第三起安全事件。
腾讯安全
2021/11/24
8920
网络托管巨头百万数据外泄、超900万安卓设备感染木马|11月24日全球网络安全热点
苹果封神头显Vision Pro竟暗藏「脑机接口」!苹果前员工疯狂揭秘读心操控
正如库克所称,这将开启「空间计算」时代,足见Vision Pro对所有人来说意义非凡。
新智元
2023/08/05
2350
苹果封神头显Vision Pro竟暗藏「脑机接口」!苹果前员工疯狂揭秘读心操控
FreeBuf 周报 | 蓝牙曝底层安全漏洞;美国水务局遭遇黑客攻击
各位 Buffer 周末好,以下是本周「FreeBuf周报」,我们总结推荐了本周的热点资讯、安全事件、一周好文和省心工具,保证大家不错过本周的每一个重点!
FB客服
2023/12/02
2910
FreeBuf 周报 | 蓝牙曝底层安全漏洞;美国水务局遭遇黑客攻击
苹果推出全新AI系统,还将接入ChatGPT!马斯克:将禁用苹果设备!
美国东部时间6月10日周一,苹果全球开发者大会(WWDC)正式召开。苹果公司CEO库克等苹果高管介绍了面向iPhone、iPad和Mac电脑、到智能手表Apple Watch、混合现实头显Vision Pro等硬件的全新操作系统(OS)。据介绍,这些OS的测试版都将在7月推出,今年秋季正式上线。
芯智讯
2024/06/18
2540
苹果推出全新AI系统,还将接入ChatGPT!马斯克:将禁用苹果设备!
全球37%手机或因芯片漏洞遭攻击、黑客利用微软漏洞窃取登录凭据|全球网络安全热点
以打击中东目标而闻名的威胁行为者再次改进了其Android间谍软件,增强了功能,使其更隐蔽、更持久,同时伪装成看似无害的应用程序更新,以保持在雷达之下。
腾讯安全
2021/11/25
7490
全球37%手机或因芯片漏洞遭攻击、黑客利用微软漏洞窃取登录凭据|全球网络安全热点
BBA也无法幸免,这些汽车品牌曾被黑客攻击
3月22日,世界黑客大赛(Pwn2Own)在温哥华拉开序幕。2023 Pwn2Own为期三天,主办方为本届比赛总计准备了108万美元奖金,来自全球各个国家和地区的安全专家大展神通,纷纷向知名品牌发起网络攻击。 在Pwn2Own大赛上,就有黑客成功攻破特斯拉汽车安全防护,而且是攻破了“两次”,也因此获得了大量的赏金。 第一天,Synacktiv团队演示了针对特斯拉Gateway 的 TOCTOU的竞态条件漏洞攻击。他们获得了 10万美元和 10 个 Master of Pwn 积分,并额外获赠了一辆特斯拉Mo
FB客服
2023/04/04
4550
BBA也无法幸免,这些汽车品牌曾被黑客攻击
Spring框架可远程执行漏洞攻击、全球最大暗网市场Hydra被取缔、印尼天然气巨头PGN遭勒索攻击|网络安全周报
2022年4月4日至4月8日共收录全球网络安全热点8项,涉及Hydra、PGN、Nordex等。
腾讯安全
2022/04/08
5700
Spring框架可远程执行漏洞攻击、全球最大暗网市场Hydra被取缔、印尼天然气巨头PGN遭勒索攻击|网络安全周报
苹果耳机AirPods Max(Pro)的空间音频技术,Unity端开源框架下载
关于更多机器学习、人工智能、增强现实、Unity、Unreal资源和技术干货,可以关注公众号:AIRX社区
三次方AIRX
2020/12/10
1.3K0
推荐阅读
相关推荐
3个月挖到55个漏洞,这伙白帽获苹果超330万元的赏金
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验