【问题标题】:Mongo Operations getting starvedMongo Operations 饿死了
【发布时间】:2018-07-16 22:28:33
【问题描述】:

Mongo db 操作在rabbit mq 消费者中变得饥饿。

rabbitConn.createChannel(function(err, channel) {
channel.consume(q.queue, async function(msg) {
    // The consumer listens to messages on Queue A for suppose based on a binding key.

    await Conversations.findOneAndUpdate(
        {'_id': 'someID'},
        {'$push': {'messages': {'body': 'message body'}}}, function(error, count) {
            // Passing a call back  so that the query is executed immediately as mentioned in the
            // mongoose document http://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate
        });
    });
});

问题是如果有大量消息被读取,当队列没有更多消息时,mongo 操作就会变得饥饿并执行。因此,如果队列中有 1000 条消息。首先读取 1000 条消息,然后调用 mongo 操作。

  1. 在不同的 nodejs 进程中运行工作程序会起作用吗?

Ans:尝试这样做将工作线程与主线程解耦,但没有帮助。

  1. 我还编写了一个有 10 个工作人员的负载平衡器,但这似乎没有帮助,事件循环是否没有优先考虑 mongo 操作?

Ans: 对 10 个工作人员从队列中读取都没有帮助,只有在队列中没有更多内容可读取时才执行 findOneAndUpdate。

任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 这里真的不够,但尝试将预取计数设置为 1 或 2(完成后您还必须确认消息),看看是否有帮助。
  • 另外,mongo 操作是每条消息调用一次,还是整体调用一次?
  • 每条消息调用一次 mongo 操作。我将尝试设置预取计数。我想我已经找到了解决办法。我尝试通过写 50 条消息来使用批量写入,这就像一个魅力。将测试更多。感谢您的及时回复。
  • 基本上,没有预取和自动确认设置,你没有消息队列。消息将直接从发布者发送到订阅者。

标签: javascript mongodb mongoose rabbitmq


【解决方案1】:

根据问题的描述,我认为你有一个没有消息队列发生的情况。当您有一堆消息在队列中,然后订阅消费者并将 auto-ack 设置为 true 并且没有预取计数时,就会发生这种情况。 This answer 更详细地描述了在这种情况下会发生什么。

如果我不得不猜测的话,我会说 javascript 代码正在花费所有分配的周期从代理下载消息,而不是将它们处理到 Mongo 中。添加预取计数,同时禁用自动确认可能会解决您的问题。

【讨论】:

  • 非常感谢!就是这样。解决了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
  • 2016-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多