如何重新启动使用者并使用被拒绝的消息

时间:2014-11-06 21:24:23

标签: python python-2.7 rabbitmq twisted amqp

将txamqp客户端与特定方案一起使用如下:

  1. 声明一个名为'messaging'的交换(type = topic)
  2. yield amqp.chan.exchange_declare(exchange='messaging', type='topic')
    
    1. 设置消费者
    2. yield amqp.named_queue_declare(queue="submit.sm_all")
      yield amqp.chan.queue_bind(queue="submit.sm_all", exchange="messaging", routing_key="submit.sm.*")
      yield amqp.chan.basic_consume(queue="submit.sm_all", no_ack=False, consumer_tag='qtag')
      
      1. 发布 50条消息
      2.    for i in range(50):
               yield amqp.publish(exchange='messaging', routing_key="submit.sm.connector01", 
                   content=Content(str(i)))
        
        1. 使用回调重新排列所有已消费的消息来启动消费者
        2. queue = yield amqp.client.queue('qtag')
          queue.get().addCallback(self._callback_reject_and_requeue_all).addErrback(self._errback)
          
          1. 5秒之后停止消费者
          2. yield queue.close()
            

            在这个阶段,队列仍然有50条消息,因为它们都被拒绝并重新排队(回调被多次激活)。

            1. 再次启动消费者:
            2. queue = yield amqp.client.queue('qtag')
              queue.get().addCallback(self._callback).addErrback(self._errback)
              
              1. 5秒之后停止消费者
              2. yield queue.close()
                

                问题是在步骤6中启动使用者之后从未触发回调,并且队列仍然有50条消息。

                注意:

                • 邮件会被拒绝:
                yield amqp.chan.basic_reject(delivery_tag=message.delivery_tag, requeue = 1)
                

2 个答案:

答案 0 :(得分:0)

消息是否被拒绝没有区别 - 它将驻留在队列之上并且可以由任何消费者挑选(或者如果您使用TTL或长度限制将被从队列中删除,并且将达到此类限制)

如果无法在服务器端定义,则不能仅使用先前被拒绝的消息。实际上,您只能从队列中消耗一个消息(它们是严格的FIFO队列)。

作为一种变通方法,您可以设置Dead Letter Exchanges并拒绝requeue=false的邮件,然后根据DLX路由流程将它们移动到目标队列。然后你可以从那里使用被拒绝的消息,但一般情况下,除非需要特殊的逻辑,否则拒绝重新排队到消耗的同一队列的消息。

你也可以在你想要的地方重新发布你想要拒绝的信息,甚至听起来有点生气。

<强> P.S:

请注意,当您在函数上调用 yield 时,不会运行函数体,而是返回生成器对象

答案 1 :(得分:0)

为了彻底停止消费者(步骤5),必须使用basic_cancel:

  1. 5秒钟后停止消费者:

    收益率amqp.chan.basic_cancel(consumer_tag =&#39; qtag&#39;)

  2. 再次启动消费者:

    产生amqp.chan.basic_consume(queue =&#34; submit.sm_all&#34;,no_ack = False,consumer_tag =&#39; qtag&#39;) queue = yield amqp.client.queue(&#39; qtag&#39;) queue.get()。的addCallback(self._callback).addErrback(self._errback)