RabbitMQ:如何限制消费率

时间:2015-03-24 06:54:06

标签: node.js performance rabbitmq message-queue

我需要限制从rabbitmq队列中消费消息的速度。

我找到了很多建议,但大多数都提供了使用预取选项。但是这个选项不能满足我的需要。即使我将预取设置为1,速率也是大约6000条消息/秒。这对消费者来说太多了。

我需要限制每秒大约70到200条消息。这意味着每5-14ms消耗一条消息。没有同步消息。

我正在使用带有amqp.node库的Node.JS。

5 个答案:

答案 0 :(得分:5)

实施令牌桶可能会有所帮助: https://en.wikipedia.org/wiki/Token_bucket

您可以编写一个生产者,以固定的速率向“令牌桶队列”生成消息上的TTL(可能在一秒钟后过期?)或者只设置一个等于每秒速率的最大队列大小。接收“正常队列”消息的消费者还必须接收“令牌桶队列”消息,以便有效地处理消息以限制应用程序。

NodeJS + amqplib示例:

def is_prime(n):
    if n<2:
       return False  # handle special case
    sn = int(n**0.5)+1  # +1 because of perfect squares like 49
    for i in range(2,sn):
        if n%i==0:
            return False
    return True

答案 1 :(得分:2)

我已经找到了解决方案。

我使用来自npm的module nanotimer来计算延迟。

然后我以纳秒为单位计算delay = 1 / [message_per_second]。

然后我使用prefetch = 1

消费消息

然后我计算延迟作为延迟 - [processing_message_time]

然后我在发送消息

之前使超时=真正延迟

完美无缺。感谢所有

答案 2 :(得分:1)

参见&#39;公平派遣&#39;在RabbitMQ Documentation

  

例如,在有两个工人的情况下,当所有奇怪的消息都很重,甚至消息很轻时,一个工人将经常忙碌而另一个工作人员几乎不会做任何工作。好吧,RabbitMQ对此一无所知,仍然会均匀地发送消息。

     

这是因为RabbitMQ只是在消息进入队列时调度消息。它没有查看消费者的未确认消息的数量。它只是盲目地向第n个消费者发送每个第n个消息。

     

为了打败我们可以使用值为1的prefetch方法。这告诉RabbitMQ一次不向一个worker发送一条消息。或者,换句话说,不要向工作人员发送新消息,直到它处理并确认了前一个消息。相反,它会将它发送给下一个仍然不忙的工人。

答案 3 :(得分:0)

我认为RabbitMQ不能为您提供开箱即用的功能。

如果你只有一个消费者,那么整个过程非常简单,只需让它在消费消息之间休息。

如果您有多个消费者,我建议您使用一些“共享内存”来保持费率。例如,您可能有10个消费者使用消息。要在所有消息中保持70-200条消息的速率,您将拨打Redis电话,看看您是否有资格处理消息。如果是,则更新Redis,向其他消费者显示当前正在处理一条消息。

如果您无法控制使用者,请执行选项1或2并将消息发布回Rabbit。这样,原始消费者将以所需的速度消费消息。

答案 4 :(得分:0)

这就是我用 settimeout 修复我的方法

我将我的设置为每 200 毫升处理一次消耗,这将在 1 秒内消耗 5 条数据我做了我的更新(如果存在)

channel.consume(transactionQueueName, async (data) => {
   let dataNew = JSON.parse(data.content);
       const processedTransaction = await seperateATransaction(dataNew);
        // delay ack to avoid duplicate entry !important dont remove the settimeout
        setTimeout(function(){
          channel.ack(data);
        },200);
 });

完成