记一次处理线上使用rocketMQ发送消息,内存99%的实践操作

1.业务与环境:

环境:springboot2.2.6.release+rocketMQ4.6+mysql5.6+Linux 4核8G内存

业务:定时任务查询mysql的list数据,使用多线程发送消息,

定时任务使用 @Scheduled 每5秒执行一次

多线程使用的是list.parallelStream()方式

发送消息Producer使用 DefaultMQProducer producer = new DefaultMQProducer();

producer.start();每次发完消息后 froducer.shutdown();

 

 

2.情况说明

线上部署大约一天后,发现数据发送比较慢,有延迟,查看日志,发现 数据处理、入库等操作消耗时间为5-60s;内存也使用彪到99%,cpu使用率是正常的。

重启后发现情况好转,但一天后又出现这种情况;

 

3.找问题

1.使用 jps -l 查看该服务的pid

2.使用jstack 导出线程使用情况,命令为

jstack -l pid > jstack.txt

3.打开jstack.txt,发现

"RequestHouseKeepingService" #95300 daemon prio=5 os_prio=0 tid=0x00007fc89271a000 nid=0x518 in Object.wait() [0x00007fc6493bc000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.util.TimerThread.mainLoop(Timer.java:552)
    - locked <0x00000000e6b5cb98> (a java.util.TaskQueue)
    at java.util.TimerThread.run(Timer.java:505)

   Locked ownable synchronizers:
    - None

RequestHouseKeepingService线程有9000+,而且都是TIMED_WAITING (on object monitor)状态,

RequestHouseKeepingService 为生产者 MQProducerInner的实现类 DefaultMQProducerImpl 下的一个属性

private final Timer timer = new Timer("RequestHouseKeepingService", true);

Timer是线程安全的,每次请求都会创建一个新的线程;

timer的线程被挂起,无线等待;猜测可能是 producer 一直在启动/关闭,timer的任务未执行完毕被挂起;

4.解决方法

使用springboot的配置文件+注入方式 注入生产者

@Autowired
DefaultMQProducer defaultMQProducer;

rocketmq:
  producer:
    group: GROUP_TEST
  name-server: 127.0.0.1:9876

不在频繁创建/启动/关闭  DefaultMQProducer ;

重新部署服务,监测运行一周,内存99%情况没有再次出现;

5.结论

此次事故是RocketMQ的生产者使用不当导致,RocketMQ还需要多多学习;

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Sequelize 是 Node.js 环境下的 ORM 框架,提供了比较完善的数据库操作支持。Sequelize 的连接池是其关键特性之一,可以在多个请求之间共享数据库连接,提升数据库查询性能。但是,连接池的配置和使用也需要注意一些细节。 在线上环境中,我们曾经遇到过 Sequelize 连接池报错“ResourceRequest timed out”的问题。经过排查,我们发现该问题主要有以下几个原因: 1. 连接池配置不合理 Sequelize 的连接池有很多配置项,比如最大连接数、最小连接数、连接超时时间等。如果这些参数设置不合理,就容易导致连接池资源不足或者连接过期。因此,我们需要根据实际需求和服务器性能,进行合理的配置。 2. 数据库连接未释放 在使用 Sequelize 连接池时,我们需要手动释放连接资源。如果没有正确释放,就会导致连接池资源耗尽。通常我们可以使用 Promise.then 或 .finally 方法来释放连接资源。 3. 数据库连接泄露 数据库连接泄露是指在应用中创建的数据库连接未被正确关闭,从而导致连接池中的连接资源逐渐耗尽。通常我们可以使用 Sequelize 提供的 sequelize.close() 方法来关闭所有数据库连接,确保连接池资源得到释放。 4. 高并发压力过大 当应用面临高并发压力时,连接池中的连接资源可能会被快速消耗完毕。此时,我们需要调整连接池的配置或者增加服务器资源,来满足高并发请求的需求。 总之,Sequelize 连接池的问题排查需要综合考虑多个因素。在实际项目中,我们可以通过监控工具、日志分析等手段,及时发现和解决连接池问题,确保应用的稳定性和性能表现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值