消息转发时间特别长

jaler 2小时前 7

前提:进行im压测,一天压了200万数据

压完200万数据后,我们变成了每秒4笔的压测。观察事件回调: message.sensitive.forward.url http://xxxx:8888/im-msg-server/im_event/message

我们的接收服务收到转发消息后立即异步进入线程池,从日志上看只有0-1毫秒就返回了 messageCallback messageId:556417394172493954,use:0

我发送了54条消息,mongo中成功存入了54条,但是这54条消息好几秒才通过http://xxxx:8888/im-msg-server/im_event/message
推送过来,54条消息整整推送了10分钟才推送完

我清理了mongo中之前压测的200万数据,重启了im-server。清空了redis。但是还是慢。不知道问题出在哪里,这里的推送原理是什么?会是哪个地方的问题导致推送特别慢?

上传的附件:
最新回复 (1)
  • wfclaw 2小时前
    引用 2
    你好,消息转发慢的问题,根本原因是:**消息转发回调是单线程队列处理的**。

    **问题分析:**

    1. 查看源码,消息转发是通过 `callbackScheduler` 执行的:
       callbackScheduler = new ThreadPoolExecutorWrapper(Executors.newScheduledThreadPool(1), 1, "callback");

       注意:线程数硬编码为 **1**。

    2. 所有消息转发(包括普通消息转发、敏感词转发、mention转发等)都提交到同一个单线程队列中执行。

    3. 压测200万数据期间,产生了大量消息转发任务,这些任务全部堆积在队列中。

    4. 你发送的54条消息虽然立即被接收(0-1毫秒),但它们需要排队等待前面积压的200万条转发任务处理完毕。

    **为什么清理mongo和redis、重启im-server后仍然慢?**

    - 重启后,如果之前的消息转发队列未清空,或者新启动后队列中仍有大量任务等待执行,单线程处理仍然会很慢。
    - 另外,消息转发使用的是OkHttp异步调用,但调度任务是单线程提交,这是瓶颈所在。

    **解决方案:**

    1. **等待队列排空**:如果压测数据已经处理完毕,等待队列中的任务全部执行完(可能需要几小时甚至更久)。

    2. **检查队列积压情况**:可以查看IM服务的日志或线程状态,确认callbackScheduler队列中还有多少任务未处理。

    3. **修改源码增加线程数(推荐)**:
       修改 `Server.java` 中:
       callbackScheduler = new ThreadPoolExecutorWrapper(Executors.newScheduledThreadPool(1), 1, "callback");
       改为更大的线程数,比如:
       callbackScheduler = new ThreadPoolExecutorWrapper(Executors.newScheduledThreadPool(4), 4, "callback");

       注意:这是一个全局回调调度器,所有回调(消息转发、事件通知等)都共享这个线程池,但增大线程数可以并行处理多个回调。

    4. **对于生产环境**:建议将回调线程数配置化,或者分离不同类型的回调到不同的线程池,避免互相影响。

    **总结:** 这不是你的接收服务问题,也不是mongo/redis问题,而是IM服务内部消息转发调度器是单线程队列,压测后大量任务堆积导致的排队延迟。
返回