基于RabbitMQ的RPC通信

基于RabbitMQ的RPC通信

当需要调用局域网中的服务时,可以用frp进行穿透,也可以在公网搭建RabbitMQ服务器做消息中转,本文演示了这个步骤。

版本信息

属性
RabbitMQ 3.13.0
pika 1.3.1
python 3.6.8
CPU 2颗 Intel® Xeon® Gold 6248R CPU @ 3.00GHz

操作步骤

搭建RabbitMQ(默认用户名:guest 密码:guest )

bash 复制代码
docker run -d --name rabbitmq -p 5671:5671 -p 5672:5672 -p 4369:4369 \
				-p 25672:25672 -p 15671:15671 -p 15672:15672 rabbitmq:management

服务端实现(srv.py)

python 复制代码
# -*- coding:utf-8 -*-
import pika
import time
import sys
import os

def request_handler(message):
    #content=message.decode('utf-8')
    #print(content)
    return message
    
def on_request(ch, method, props, body):
    response = request_handler(body)
    ch.basic_publish(exchange="",
                     routing_key=props.reply_to,
                     properties=pika.BasicProperties(
                         content_encoding='utf-8',
                         correlation_id=props.correlation_id,
                     ),
                     body=str(response))
    ch.basic_ack(delivery_tag=method.delivery_tag)

while True:
    try:
        credentials = pika.PlainCredentials("guest", "guest")
        connection = pika.BlockingConnection(pika.ConnectionParameters("127.0.0.1",port=5672, credentials=credentials))
        channel = connection.channel()
        channel.queue_declare(queue="rpc_queue")    
        channel.basic_consume("rpc_queue", on_request)
        print(" waiting requests")
        channel.start_consuming()
    except:
        print("error restart")
        pass
    time.sleep(1)

客户端实现(client.py)

python 复制代码
# -*- coding:utf-8 -*-
import os
import io
import time
import uuid
import sys
import requests
import warnings
import numpy as np
import pika
import time
import sys
import traceback
import json
import queue
import uuid
import time
import argparse

class MqRpcClient(object):
    def __init__(self):
        credentials = pika.PlainCredentials("guest", "guest")
        self.connection = pika.BlockingConnection(pika.ConnectionParameters("127.0.0.1",port=5672, credentials=credentials))
        self.channel = self.connection.channel()
        result = self.channel.queue_declare(queue="", exclusive=True)
        self.callback_queue = result.method.queue
        self.channel.basic_consume(self.callback_queue, self.on_response, True)

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

    def send(self, message,timeout=5):
        self.response = None
        self.corr_id = str(uuid.uuid4())
        self.channel.basic_publish(exchange="",
                                   routing_key="rpc_queue",
                                   properties=pika.BasicProperties(
                                       reply_to=self.callback_queue,
                                       content_encoding='utf-8',
                                       correlation_id=self.corr_id,
                                   ),
                                   body=message.encode('utf-8')) 
        t0=time.time()
        while self.response is None:
            self.connection.process_data_events()
            t1=time.time()
            if t1-t0>timeout:
                return None
        return self.response

def send_message(message,loop):
    rpc = MqRpcClient()
    t0=time.time()
    for i in range(loop):
        response = rpc.send(message,1)
        if response is None and response==message:
            print("Failed")
            break
    t1=time.time()
    print("qps:{:.2f}".format(loop/(t1-t0)))
    return True

if __name__ == "__main__":
    parse = argparse.ArgumentParser()
    parse.add_argument('--msg', type=str, default='', help='')
    parse.add_argument('--loop', type=int, default=1, help='')
    args = parse.parse_args()
    send_message(args.msg,args.loop)

性能测试(4919 qps)

bash 复制代码
# 安装依赖
pip3 install pika==1.3.1

# 启动服务端(服务端收到请求后,直接回复)
python3 srv.py &

# 客户端多路请求,测试总吞吐
cat <<EOF | tee rpc.sh
for i in \`seq 0 \$1\`
do
  python3 client.py  --msg HelloWorld --loop 1000 &
done
wait
EOF
bash rpc.sh  16 | awk -F: '{SUM+=$2};END{print SUM}'
相关推荐
冷小鱼16 小时前
消息队列(MQ)技术全景科普:从选型到AI+未来
人工智能·kafka·rabbitmq·rocketmq·mq·pulsar
染夕陌木17 小时前
RPC/服务调用框架中“方法无法应用到给定类型”错误的通用排查指南
java·ide·rpc
_F_y19 小时前
仿RabbitMQ实现消息队列-服务端核心模块实现(2)
网络·rabbitmq
io无心1 天前
SpringAMQP
rabbitmq·springamqp
fengxin_rou2 天前
RabbitMQ安装教程:windows本地安装和docker部署
java·分布式·后端·rabbitmq
Albert Edison2 天前
【RabbitMQ】RPC 通信(使用案例)
分布式·rpc·rabbitmq
lifewange2 天前
RPC 是什么
网络·网络协议·rpc
白晨并不是很能熬夜2 天前
【PRC】第 2 篇:Netty 通信层 — NIO 模型 + 自定义协议 + 心跳
java·开发语言·后端·面试·rpc·php·nio
weixin_419658313 天前
RabbitMQ 的高级特性
java·分布式·rabbitmq
白晨并不是很能熬夜3 天前
【RPC】第 1 篇:全景篇 — 一次 RPC 调用的完整旅程
java·网络·后端·网络协议·面试·rpc·java-zookeeper