繁体   English   中英

使用Pika的Rabbitmq远程通话

[英]Rabbitmq remote call with Pika

我是Rabbitmq的新手,并试图通过本教程( https://www.rabbitmq.com/tutorials/tutorial-six-python.html )使客户端如何请求服务器提供有关内存和CPU利用率的信息。 。

因此,客户端请求CPU和内存(我相信我将需要两个队列),服务器将使用这些值进行响应。

无论如何,在这种情况下,可以使用Python中的Pika库简单地创建一个client.pyserver.py

如果您还没有的话,我建议您先阅读RabbitMQ教程 RPC示例基于先前示例(直接队列,排他队列,确认等)中涵盖的概念。

本教程中提出的RPC解决方案至少需要两个队列,具体取决于您要使用多少个客户端:

  • 一个直接队列( rpc_queue ),用于将请求从客户端发送到服务器。
  • 每个客户端一个独占队列,用于接收响应。

请求/响应周期:

  • 客户端将消息发送到rpc_queue 每个消息包括一个reply_to属性,与所述客户端独占队列服务器应该答复的名称,和一个correlation_id属性,它是用来跟踪请求只是一个唯一的ID。
  • 服务器在rpc_queue上等待消息。 消息到达时,它将准备响应,将correlation_id添加到新消息,然后将其发送到在reply_to message属性中定义的队列。
  • 客户端等待其排他队列,直到找到最初生成的具有correlation_id的消息。

直接跳到您的问题,首先要做的是定义要在响应中使用的消息格式。 您可以使用JSON,msgpack或任何其他序列化库。 例如,如果使用JSON,一条消息可能看起来像这样:

{
    "cpu": 1.2,
    "memory": 0.3
} 

然后,在您的server.py

def on_request(channel, method, props, body):
    response = {'cpu': current_cpu_usage(),
                'memory': current_memory_usage()}
    properties = pika.BasicProperties(correlation_id=props.correlation_id)

    channel.basic_publish(exchange='',
                          routing_key=props.reply_to,
                          properties=properties,
                          body=json.dumps(response))
    channel.basic_ack(delivery_tag=method.delivery_tag)

# ...

并在您的client.py

class ResponseTimeout(Exception): pass

class Client:
    # similar constructor as `FibonacciRpcClient` from tutorial...

    def on_response(self, channel, method, props, body):
        if self.correlation_id == props.correlation_id:
            self.response = json.loads(body.decode())

    def call(self, timeout=2):
        self.response = None
        self.correlation_id = str(uuid.uuid4())
        self.channel.basic_publish(exchange='',
                                   routing_key='rpc_queue',
                                   properties=pika.BasicProperties(
                                       reply_to=self.callback_queue,
                                       correlation_id=self.correlation_id),
                                   body='')

        start_time = time.time()
        while self.response is None:
            if (start_time + timeout) < time.time():
                raise ResponseTimeout()
            self.connection.process_data_events()
        return self.response

如您所见,代码与原始FibonacciRpcClient几乎相同。 主要区别在于:

  • 我们使用JSON作为消息的数据格式。
  • 我们的客户端call()方法不需要body参数(没有任何内容可发送到服务器)
  • 我们负责响应超时(如果服务器已关闭,或者它没有回复我们的消息)

不过,这里还有很多地方需要改进:

  • 没有错误处理:例如,如果客户端“忘记了”发送一个reply_to队列,我们​​的服务器将崩溃,并且将在重新启动时再次崩溃(只要我们的服务器未确认该破损的消息就会无限地重新排队) )
  • 我们不处理断开的连接(没有重新连接机制)
  • ...

您也可以考虑使用发布/订阅模式替换RPC方法。 这样,服务器只需在每个X时间间隔内广播其CPU /内存状态,一个或多个客户端就可以接收更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM