Python RabbitMQ消息隊(duì)列實(shí)現(xiàn)rpc
上個(gè)項(xiàng)目中用到了ActiveMQ,只是簡(jiǎn)單應(yīng)用,安裝完成后直接是用就可以了。由于新項(xiàng)目中一些硬件的限制,需要把消息隊(duì)列換成RabbitMQ。
RabbitMQ中的幾種模式和機(jī)制比ActiveMQ多多了,根據(jù)業(yè)務(wù)需要,使用RPC實(shí)現(xiàn)功能,其中踩過的一些坑,有必要記錄一下了。

上代碼,目錄結(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)碼問題 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í)有所幫助,也希望大家多多支持腳本之家。
- Python rabbitMQ如何實(shí)現(xiàn)生產(chǎn)消費(fèi)者模式
- Python RabbitMQ實(shí)現(xiàn)簡(jiǎn)單的進(jìn)程間通信示例
- Python實(shí)現(xiàn)RabbitMQ6種消息模型的示例代碼
- Python隊(duì)列RabbitMQ 使用方法實(shí)例記錄
- Python操作rabbitMQ的示例代碼
- python實(shí)現(xiàn)RabbitMQ的消息隊(duì)列的示例代碼
- python RabbitMQ 使用詳細(xì)介紹(小結(jié))
- Python+Pika+RabbitMQ環(huán)境部署及實(shí)現(xiàn)工作隊(duì)列的實(shí)例教程
- 利用Python學(xué)習(xí)RabbitMQ消息隊(duì)列
- 基于python實(shí)現(xiàn)監(jiān)聽Rabbitmq系統(tǒng)日志代碼示例
相關(guān)文章
python操作mysql實(shí)現(xiàn)一個(gè)超市管理系統(tǒng)
超市管理系統(tǒng)有管理員和普通用戶兩條分支,只需掌握Python基礎(chǔ)語法,就可以完成這個(gè)項(xiàng)目,下面這篇文章主要給大家介紹了關(guān)于python操作mysql實(shí)現(xiàn)一個(gè)超市管理系統(tǒng)的相關(guān)資料,需要的朋友可以參考下2022-12-12
深入淺析NumPy庫(kù)中的numpy.diag()函數(shù)
通過本文的介紹,我們深入了解了NumPy庫(kù)中numpy.diag()函數(shù)的用法和應(yīng)用,從基本用法到高級(jí)特性,再到在線性代數(shù)中的應(yīng)用,我們逐步展示了numpy.diag()在處理對(duì)角矩陣和相關(guān)問題時(shí)的強(qiáng)大功能,需要的朋友可以參考下2024-05-05
Python實(shí)現(xiàn)對(duì)比不同字體中的同一字符的顯示效果
這篇文章主要介紹了Python實(shí)現(xiàn)對(duì)比不同字體中的同一字符的顯示效果,也就是對(duì)比不同字體中某個(gè)字的顯示效果,這在做設(shè)計(jì)時(shí)非常有用,需要的朋友可以參考下2015-04-04
python自定義函數(shù)中的return和print使用及說明
這篇文章主要介紹了python自定義函數(shù)中的return和print使用及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
python?kornia計(jì)算機(jī)視覺庫(kù)實(shí)現(xiàn)圖像變化
這篇文章主要為大家介紹了python?kornia計(jì)算機(jī)視覺庫(kù)實(shí)現(xiàn)圖像變化算法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
Python動(dòng)刷新12306火車票的代碼(附源碼)
這篇文章主要介紹了Python動(dòng)刷新12306火車票的完整代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2018-01-01
Python+drawpad實(shí)現(xiàn)CPU監(jiān)控小程序
這篇文章主要為大家詳細(xì)介紹了如何利用Python+drawpad實(shí)現(xiàn)一個(gè)簡(jiǎn)單的CPU監(jiān)控小程序,文中示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下2022-08-08
CentOS 7下安裝Python3.6 及遇到的問題小結(jié)
這篇文章主要介紹了CentOS 7下安裝Python3.6 及遇到的問題小結(jié),需要的朋友可以參考下2018-11-11

