如何在pika和Rabbitmq中使用多线程来执行请求和响应RPC消息

时间:2019-05-27 14:57:39

标签: python multithreading rabbitmq pika

我正在使用Rabbitmq开发一个项目,正在使用RPC模式,基本上是从队列接收或使用消息,进行一些处理,然后将响应发送回去。我正在使用Pika,我的目标是为每个任务使用一个线程,因此对于每个任务,我都会为该任务专门创建一个线程。我还读到,最佳实践是仅建立一个Connection,并在其下建立多个通道,但我总是遇到此错误:
 “可能不会从“”的范围调用“ start_consumption” pika.exceptions.RecursionError:可能无法从另一个BlockingConnection或BlockingChannel回调的范围中调用start_using。

我进行了一些研究,发现Pika不是线程安全的,我们应该为每个线程使用独立连接和通道。但是我不想这样做,因为它被认为是不好的做法。因此,我想在这里问是否有人已经完成这项工作。我还读到,如果我不使用BlockingConnection实例化我的Connection是可能的,并且还有一个名为add_callback_threadsafe的函数可以使之成为可能。但是遗憾的是没有示例,我阅读了文档,但是它很复杂,没有示例,我很难理解他们想要描述的内容。

我的尝试是声明两个类。每个类将代表一个任务执行器,该任务执行器从队列中接收或使用消息,并基于该消息进行一些处理并将响应传递回去。我的想法是在两个任务之间共享Rabbitmq连接,但是每个任务都会获得一个独立的Channel。在传递给函数的Rabbit参数上方的代码中,是一个类,其中包含一些变量(例如Connection)和其他函数(例如EventSubscriber),当调用该函数时,它将分配一个新的Channel并开始使用来自特定Exchange和routingKey的消息。接下来,我声明一个线程,并为该线程提供订阅或使用功能作为目标。其他任务类也与此类相同,这就是为什么我只上传此代码的原因。在主类中,我与Rabbitmq建立连接,并将其作为参数传递给两个任务类的构造函数。

On_Deregistration类:

def __init__(self, rabbit):
   self.event(rabbit) # this will call event function and pass the connection shared between all Tasks. rabbit parameter hold a connection to rabbitmq

def event(self, rabbit):

    self.Subscriber = rabbit.EventSubscriber(rabbit,  'testing.test',  'test', False,  onDeregistrationFromHRS # this func is task listener)

def subscribeAsync(self):
    self.Subscriber.subscribe() # here i call start_consuming

def start(self):
    """start Subscribtion in an Independant Thread  """
    thread = threading.Thread(target = self.subscribeAsync )  
    thread.start()
    if thread.isAlive():
        print("asynchronous subscription started")

主班:

类应用:

def __init__(self):

    self.rabbitMq = RabbitMqCommunicationInterface(host='evallx033.emea.porsche.biz', port=5672)
    firstTask =  On_Deregistration(self.rabbitMq)
    secondTask =  secondTask(self.rabbitMq)

app = App()

错误:“可能无法从'

的范围调用start_using

pika.exceptions.RecursionError:可能无法从另一个BlockingConnection或BlockingChannel回调的范围中调用start_using

我搜索了此错误的原因,显然pika不是线程安全的,但必须对此有解决方案。也许不使用BlockingConnection吗?也许有人可以给我一个例子,因为我尝试了一下却没有起作用。也许我缺少有关如何使用rabbitmq实现多线程的东西

1 个答案:

答案 0 :(得分:0)

因此,经过长时间的研究,我发现Pika不是线程安全的。至少就目前而言,这可能是线程安全的。所以现在对于我的项目,我不再使用Pika,而是使用Rabbitpy,后者是线程安全的库。但是我必须说Pika是一个很棒的库,而且我发现API比Rabbitpy更好地描述和构造了API,但是对于我的项目,必须使用多线程,这就是为什么Pika目前不是一个好选择。我希望这对将来的人有帮助