欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python RabbitMQ消息隊(duì)列實(shí)現(xiàn)rpc

 更新時(shí)間:2018年05月30日 08:27:11   作者:dugufei  
這篇文章主要介紹了python 之rabbitmq實(shí)現(xiàn)rpc,主要實(shí)現(xiàn)客戶端通過(guò)發(fā)送命令來(lái)調(diào)用服務(wù)端的某些服務(wù),服務(wù)端把結(jié)果再返回給客戶端,感興趣的小伙伴們可以參考一下

上個(gè)項(xiàng)目中用到了ActiveMQ,只是簡(jiǎn)單應(yīng)用,安裝完成后直接是用就可以了。由于新項(xiàng)目中一些硬件的限制,需要把消息隊(duì)列換成RabbitMQ。

RabbitMQ中的幾種模式和機(jī)制比ActiveMQ多多了,根據(jù)業(yè)務(wù)需要,使用RPC實(shí)現(xiàn)功能,其中踩過(guò)的一些坑,有必要記錄一下了。

上代碼,目錄結(jié)構(gòu)分為 c_server、c_client、c_hanlder:

c_server:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pika
import time
import json
import io
import yaml

s_exchange = input("請(qǐng)輸入交換機(jī)名稱->>").decode('utf-8').strip()
s_queue = input("輸入消息隊(duì)列名稱->>").decode('utf-8').strip()
credentials = pika.PlainCredentials('system', 'manager')
connection = pika.BlockingConnection(pika.ConnectionParameters(host='XXX.XXX.XXX.XXX',credentials=credentials))
# 定義
channel = connection.channel()
channel.exchange_declare(exchange=s_exchange, exchange_type='direct')
channel.queue_declare(queue=s_queue, exclusive=True)
channel.queue_bind(queue=s_queue, exchange=s_exchange)

def s_manage(content):
 # 解決unicode轉(zhuǎn)碼問(wèn)題 json.JSONDecoder().decode(content)
 str_content = yaml.safe_load(json.loads(content,encoding='utf-8'))
 str_res = {
  "errorid": 0,
  "resp": str_content['cmd'],
  "errorcont": "成功"
 }
 return json.dumps(str_res)

def on_request(ch, method, props, body):
 response = s_manage(body)
 ch.basic_publish(exchange='',
      routing_key=props.reply_to,
      properties=pika.BasicProperties(correlation_id = \
               props.correlation_id),
      body=response)
 ch.basic_ack(delivery_tag = method.delivery_tag)

channel.basic_qos(prefetch_count=1)
channel.basic_consume(on_request, queue=s_queue)

print(" [x] Awaiting RPC requests")
channel.start_consuming()

c_client:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import pika
import uuid
import json
import io

class RpcClient(object):
  def __init__(self):
    self.credentials = pika.PlainCredentials('guest', 'guest')
    self.connection = pika.BlockingConnection(pika.ConnectionParameters(host='XXX.XXX.XXX.XXX',
                                credentials=self.credentials))
    self.channel = self.connection.channel()

  def on_response(self, ch, method, props, body):
    if self.callback_id == props.correlation_id:
      self.response = body
    ch.basic_ack(delivery_tag=method.delivery_tag)

  def get_response(self, callback_queue, callback_id):
    '''取隊(duì)列里的值,獲取callback_queued的執(zhí)行結(jié)果'''
    self.callback_id = callback_id
    self.response = None
    self.channel.queue_declare('q_manager', durable=True)
    self.channel.basic_consume(self.on_response, # 只要收到消息就執(zhí)行on_response
                  queue=callback_queue)
    while self.response is None:
      self.connection.process_data_events() # 非阻塞版的start_consuming
    return self.response

  def call(self, queue_name, command, exchange,rout_key): # 命令下發(fā)
    '''隊(duì)列里發(fā)送數(shù)據(jù)'''
    # result = self.channel.queue_declare(exclusive=False) #exclusive=False 必須這樣寫
    self.callback_queue = 'q_manager' # result.method.queue
    self.corr_id = str(uuid.uuid4())
    self.channel.basic_publish(exchange=exchange,
                  routing_key=queue_name,
                  properties=pika.BasicProperties(
                    reply_to=self.callback_queue, # 發(fā)送返回信息的隊(duì)列name
                    correlation_id=self.corr_id, # 發(fā)送uuid 相當(dāng)于驗(yàn)證碼
                  ),
                  body=command)
    return self.callback_queue,self.corr_id

client

c_handler:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from c_client import *
import random, time
import threading
import json
import sys

class Handler(object):
  def __init__(self):
    self.information = {}  # 后臺(tái)進(jìn)程信息

  def check_all(self, *args):
    '''查看所有信息'''
    time.sleep(2)
    print('獲取消息')
    for key in self.information:
      print("cid【%s】\t 隊(duì)列【%s】\t 命令【%s】"%(key, self.information[key][0],
                               self.information[key][1]))

  def check_task(self, cmd):
    '''查看task_id執(zhí)行結(jié)果'''
    time.sleep(2)
    try:
      task_id = int(cmd)
      print(task_id)
      callback_queue= self.information[task_id][2]
      callback_id= self.information[task_id][3]
      client = RpcClient()
      response = client.get_response(callback_queue, callback_id)
      print(response)
      # print(response.decode())
      del self.information[task_id]

    except KeyError as e :
      print("error: [%s]" % e)
    except IndexError as e:
      print("error: [%s]" % e)

  def run(self, user_cmd, host, exchange='', rout_key='',que=''):
    try:
      time.sleep(2)
      command = user_cmd
      task_id = random.randint(10000, 99999)
      client = RpcClient()
      response = client.call(queue_name=host, command=command,exchange=exchange,rout_key=que)
      self.information[task_id] = [host, command, response[0], response[1]]
    except IndexError as e:
      print("[error]:%s"%e)

  def reflect(self, str,cmd,host,exchange,que):
    '''反射'''
    if hasattr(self, str):
      getattr(self, str)(cmd,host,exchange,que)

  def start(self, m,cmd, host, exchange,que):
    while True:
      user_resp = input("輸入處理消息內(nèi)容ID->>").decode('utf-8').strip()
      self.check_task(user_resp)
      str = m
      print(self.information)
      t1 = threading.Thread(target=self.reflect, args=(str,cmd,host,exchange,que)) #多線程
      t1.start()

s_exchange = input("請(qǐng)輸入交換機(jī)名稱->>").decode('utf-8').strip()
s_queue = input("輸入消息隊(duì)列名稱->>").decode('utf-8').strip()
d_cmd_state =input("輸入json命令->>").decode('utf-8').strip()
s_cmd = json.dumps(d_cmd_state)
handler = Handler()
handler.start('run',s_cmd, s_queue, s_exchange, s_queue)

handler

注意要點(diǎn):1、c_client 發(fā)布消息到rabbitmq 需要攜帶 服務(wù)器返回的隊(duì)列名稱,及corr_id

2、c_handler 做了處理,每次發(fā)送的內(nèi)容都會(huì)放到task列表中,直到顯示ID號(hào),就可以查詢返回的內(nèi)容,調(diào)用如下:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python API 操作Hadoop hdfs詳解

    Python API 操作Hadoop hdfs詳解

    這篇文章主要介紹了Python API 操作Hadoop hdfs詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-06
  • Pytorch如何快速計(jì)算余弦相似性矩陣

    Pytorch如何快速計(jì)算余弦相似性矩陣

    這篇文章主要介紹了Pytorch如何快速計(jì)算余弦相似性矩陣問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Python docx庫(kù)用法示例分析

    Python docx庫(kù)用法示例分析

    這篇文章主要介紹了Python docx庫(kù)用法,結(jié)合實(shí)例形式分析了docx庫(kù)相關(guān)的docx文件讀取、文本添加、格式操作,需要的朋友可以參考下
    2019-02-02
  • Python實(shí)現(xiàn)多任務(wù)進(jìn)程示例

    Python實(shí)現(xiàn)多任務(wù)進(jìn)程示例

    大家好,本篇文章主要講的是Python實(shí)現(xiàn)多任務(wù)進(jìn)程示例,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • 使用Keras中的ImageDataGenerator進(jìn)行批次讀圖方式

    使用Keras中的ImageDataGenerator進(jìn)行批次讀圖方式

    這篇文章主要介紹了使用Keras中的ImageDataGenerator進(jìn)行批次讀圖方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-06
  • Django ORM查詢操作方式

    Django ORM查詢操作方式

    Django提供了一套非常方便的類似SqlAlchemy ORM的通過(guò)對(duì)象調(diào)用的方式操作數(shù)據(jù)庫(kù)表的ORM框架,,本文給大家詳細(xì)介紹Django ORM查詢操作方式,感興趣的朋友一起看看吧
    2023-10-10
  • Python制作一個(gè)仿QQ辦公版的圖形登錄界面

    Python制作一個(gè)仿QQ辦公版的圖形登錄界面

    這篇文章主要介紹了Python制作一個(gè)仿QQ辦公版的圖形登錄界面,幫助大家更好的理解和使用python,感興趣的朋友可以了解下
    2020-09-09
  • python下載的庫(kù)包存放路徑

    python下載的庫(kù)包存放路徑

    在本篇文章里小編給大家整理的是一篇關(guān)于python下載的庫(kù)包存放路徑,需要的朋友們可以參考學(xué)習(xí)下。
    2020-07-07
  • Python Django 命名空間模式的實(shí)現(xiàn)

    Python Django 命名空間模式的實(shí)現(xiàn)

    這篇文章主要介紹了Python Django 命名空間模式的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • 關(guān)于Python3爬蟲利器Appium的安裝步驟

    關(guān)于Python3爬蟲利器Appium的安裝步驟

    在本篇文章里小編給大家整理的是一篇關(guān)于Python3爬蟲利器Appium的安裝步驟,需要的朋友們可以跟著參考下。
    2020-07-07

最新評(píng)論