簡體   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