2013-12-18 49 views
6

我正在使用basic_consume()接收消息,并且使用basic_cancel取消消费,但存在问题。如何在rabbitmq中暂停并恢复消费优雅,pika python

这里是pika.channel

def basic_consume(self, consumer_callback, queue='', no_ack=False, 
         exclusive=False, consumer_tag=None): 
     """Sends the AMQP command Basic.Consume to the broker and binds messages 
     for the consumer_tag to the consumer callback. If you do not pass in 
     a consumer_tag, one will be automatically generated for you. Returns 
     the consumer tag. 

     For more information on basic_consume, see: 
     http://www.rabbitmq.com/amqp-0-9-1-reference.html#basic.consume 

     :param method consumer_callback: The method to callback when consuming 
     :param queue: The queue to consume from 
     :type queue: str or unicode 
     :param bool no_ack: Tell the broker to not expect a response 
     :param bool exclusive: Don't allow other consumers on the queue 
     :param consumer_tag: Specify your own consumer tag 
     :type consumer_tag: str or unicode 
     :rtype: str 

     """ 
     self._validate_channel_and_callback(consumer_callback) 

     # If a consumer tag was not passed, create one 
     consumer_tag = consumer_tag or 'ctag%i.%s' % (self.channel_number, 
                 uuid.uuid4().get_hex()) 

     if consumer_tag in self._consumers or consumer_tag in self._cancelled: 
      raise exceptions.DuplicateConsumerTag(consumer_tag) 

     self._consumers[consumer_tag] = consumer_callback 
     self._pending[consumer_tag] = list() 
     self._rpc(spec.Basic.Consume(queue=queue, 
            consumer_tag=consumer_tag, 
            no_ack=no_ack, 
            exclusive=exclusive), 
          self._on_eventok, 
          [(spec.Basic.ConsumeOk, 
          {'consumer_tag': consumer_tag})]) 

     return consumer_tag 

def basic_cancel(self, callback=None, consumer_tag='', nowait=False): 
     """This method cancels a consumer. This does not affect already 
     delivered messages, but it does mean the server will not send any more 
     messages for that consumer. The client may receive an arbitrary number 
     of messages in between sending the cancel method and receiving the 
     cancel-ok reply. It may also be sent from the server to the client in 
     the event of the consumer being unexpectedly cancelled (i.e. cancelled 
     for any reason other than the server receiving the corresponding 
     basic.cancel from the client). This allows clients to be notified of 
     the loss of consumers due to events such as queue deletion. 

     :param method callback: Method to call for a Basic.CancelOk response 
     :param str consumer_tag: Identifier for the consumer 
     :param bool nowait: Do not expect a Basic.CancelOk response 
     :raises: ValueError 

     """ 
     self._validate_channel_and_callback(callback) 
     if consumer_tag not in self.consumer_tags: 
      return 
     if callback: 
      if nowait is True: 
       raise ValueError('Can not pass a callback if nowait is True') 
      self.callbacks.add(self.channel_number, 
           spec.Basic.CancelOk, 
           callback) 
     self._cancelled.append(consumer_tag) 
     self._rpc(spec.Basic.Cancel(consumer_tag=consumer_tag, 
            nowait=nowait), 
        self._on_cancelok, 
        [(spec.Basic.CancelOk, 
        {'consumer_tag': consumer_tag})] if nowait is False else []) 

正如你可以看到每一个我取消消费consumer_tag时间的代码添加到列表_canceled。如果我再次在basic_consume中使用此标记,则会引发duplicateConsumer异常。 那么,我可以每次使用一个新的consumer_tag,但事实上我不是。因为早晚产生的标签将与之前的标签完全匹配。

我应该如何在pika中优雅地暂停和恢复消费?

回答

1

你有什么理由为自己定义你自己的consumer_tags?您可以传递一个空字符串,并让RabbitMQ为您生成消费者标签。来自basic.consume的回复,即basic.consume-ok将返回生成的consumer_tag,以便您稍后可以使用它来停止使用。

参见:http://www.rabbitmq.com/amqp-0-9-1-reference.html#basic.consume-ok

+0

从附加的pika模块代码中可以看出,即使在客户端应用程序没有指定消费者标签的情况下,pika模块也会生成一个并将其包含在消费请求中。 – mike

1

这看起来像鼠兔是做更多比它应该 - 它并不需要创建一个消费者标记,如果没有提供一个(服务器会),它也并不需要观察重复的消费者标签(服务器支持使用相同标签恢复)。

所以我不知道如何用Pika来做到这一点 - 我提供了一个错误。