一:RabbitMQ实现RPC调用

客户端:

import pika
import uuid class FibonacciRpcClient(object): def __init__(self): self.credentials = pika.PlainCredentials("admin", "admin")
self.connection = pika.BlockingConnection(pika.ConnectionParameters('10.0.0.200', credentials=self.credentials))
self.channel = self.connection.channel() result = self.channel.queue_declare(queue='', exclusive=True)
self.callback_queue = result.method.queue self.channel.basic_consume(
queue=self.callback_queue,
on_message_callback=self.on_response,
auto_ack=True) def on_response(self, ch, method, props, body):
if self.corr_id == props.correlation_id:
self.response = body def call(self, n):
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,
correlation_id=self.corr_id,
),
body=str(n))
while self.response is None:
self.connection.process_data_events()
return int(self.response) fibonacci_rpc = FibonacciRpcClient() print(" [x] Requesting fib(30)")
response = fibonacci_rpc.call(10) # 外界看上去,就像调用本地的call()函数一样
print(" [.] Got %r" % response)

服务端:

import pika

credentials = pika.PlainCredentials("admin", "admin")
connection = pika.BlockingConnection(pika.ConnectionParameters('10.0.0.200', credentials=credentials))
channel = connection.channel() channel.queue_declare(queue='rpc_queue') def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n - 1) + fib(n - 2) def on_request(ch, method, props, body):
n = int(body) print(" [.] fib(%s)" % n)
response = fib(n) ch.basic_publish(exchange='',
routing_key=props.reply_to,
properties=pika.BasicProperties(correlation_id=props.correlation_id),
body=str(response))
ch.basic_ack(delivery_tag=method.delivery_tag) channel.basic_qos(prefetch_count=1)
channel.basic_consume(queue='rpc_queue', on_message_callback=on_request) print(" [x] Awaiting RPC requests")
channel.start_consuming()

二、python中的rpc框架

SimpleXMLRPCServer

python自带的SimpleXMLRPCServer,数据包大,速度慢。

使用

只需要在服务端定义一个类,类内定义需要被调用的变量及方法,

客户端通过连接服务端,然后直接调用该类即可

服务端

from xmlrpc.server import SimpleXMLRPCServer
class RPCServer(object): def __init__(self):
super(RPCServer, self).__init__()
print(self)
self.send_data = {'server:'+str(i): i for i in range(100)}
self.recv_data = None def getObj(self):
print('get data')
return self.send_data def sendObj(self, data):
print('send data')
self.recv_data = data
print(self.recv_data)
# SimpleXMLRPCServer
server = SimpleXMLRPCServer(('localhost',4242), allow_none=True)
server.register_introspection_functions()
server.register_instance(RPCServer())
server.serve_forever()

客户端

import time
from xmlrpc.client import ServerProxy # SimpleXMLRPCServer
def xmlrpc_client():
print('xmlrpc client')
c = ServerProxy('http://localhost:4242')
data = {'client:'+str(i): i for i in range(100)}
start = time.clock() # python3.8后不支持clock(),改用perf_counter()
for i in range(50):
a=c.getObj()
print(a)
for i in range(50):
c.sendObj(data)
print('xmlrpc total time %s' % (time.clock() - start)) # python3.8后不支持clock(),改用perf_counter() if __name__ == '__main__':
xmlrpc_client()

ZeroRPC实现RPC

第三方的ZeroRPC(底层使用ZeroMQ和MessagePack),速度快,响应时间短,并发高。除此外第三方的还有grpc(谷歌推出,支持跨语言)

使用

只需要在服务端定义一个类,类内定义需要被调用的变量及方法,

客户端通过连接服务端,然后直接调用该类即可

服务端

import zerorpc

class RPCServer(object):

    def __init__(self):
super(RPCServer, self).__init__()
print(self)
self.send_data = {'server:'+str(i): i for i in range(100)}
self.recv_data = None def getObj(self):
print('get data')
return self.send_data def sendObj(self, data):
print('send data')
self.recv_data = data
print(self.recv_data)
# zerorpc
s = zerorpc.Server(RPCServer())
s.bind('tcp://0.0.0.0:4243')
s.run()

客户端

import zerorpc
import time
# zerorpc
def zerorpc_client():
print('zerorpc client')
c = zerorpc.Client()
c.connect('tcp://127.0.0.1:4243')
data = {'client:'+str(i): i for i in range(100)}
start = time.clock()
for i in range(500):
a=c.getObj()
print(a)
for i in range(500):
c.sendObj(data) print('total time %s' % (time.clock() - start)) if __name__ == '__main__':
zerorpc_client()

SimpleXMLRPCServer 和 ZeroRPC比较:

利用远程调用同样的方法,执行500次,ZeroRPC耗时大幅度的小于SimpleXMLRPCServer,所以,推荐使用ZeroRPC

三种方式实现RPC调用的更多相关文章

  1. JS基础语法---创建对象---三种方式创建对象:调用系统的构造函数;自定义构造函数;字面量的方式

    创建对象三种方式: 调用系统的构造函数创建对象 自定义构造函数创建对象(结合第一种和需求通过工厂模式创建对象) 字面量的方式创建对象 第一种:调用系统的构造函数创建对象 //小苏举例子: //实例化对 ...

  2. [OpenSource]浅谈.Net和Java互相调用的三种方式

    在很多的大型系统开发中,开发工具往往不限制于同一种开发语言,而是会使用多种开发语言的混合型开发.目前Java和.Net都声称自己占85%的市场份额,不管谁对谁错,Java和.Net是目前应用开发的两个 ...

  3. 浅谈.Net和Java互相调用的三种方式

    在很多的大型系统开发中,开发工具往往不限制于同一种开发语言,而是会使用多种开发语言的混合型开发.目前Java和.Net都声称自己占85%的市场份 额,不管谁对谁错,Java和.Net是目前应用开发的两 ...

  4. Struts2方法调用的三种方式

    在Struts2中方法调用概括起来主要有三种形式 第一种方式:指定method属性 <action name="student" class="com.itmyho ...

  5. 调用awk的三种方式

    调用awk的三种方式 调用awk有三种方式,一种为Shell命令行方式,另外两种是将awk程序写入脚本文件,然后执行该脚本文件.三种方式的命令格式归纳如下: 一.在Shell命令行输入命令调用awk, ...

  6. 调用sed命令的三种方式

    调用sed命令的三种方式 调用sed有三种方式,一种为Shell命令行方式,另外两种是将sed命令写入脚本文件,然后执行该脚本文件. 三种方式的命令格式归纳如下: 一.在Shell命令行输入命令调用s ...

  7. Solidity的三种合约间的调用方式 call、delegatecall 和 callcode

    0x00 前言 Solidity(http://solidity.readthedocs.io/en/v0.4.24/) 是一种用与编写以太坊智能合约的高级语言,语法类似于 JavaScript. S ...

  8. python 全栈开发,Day94(Promise,箭头函数,Django REST framework,生成json数据三种方式,serializers,Postman使用,外部python脚本调用django)

    昨日内容回顾 1. 内容回顾 1. VueX VueX分三部分 1. state 2. mutations 3. actions 存放数据 修改数据的唯一方式 异步操作 修改state中数据的步骤: ...

  9. Struts2方法调用的三种方式(有新的!调用方法的说明)

    在Struts2中方法调用概括起来主要有三种形式 第一种方式:指定method属性 <action name="heroAction" class="com.ABC ...

  10. java:struts框架2(方法的动态和静态调用,获取Servlet API三种方式(推荐IOC(控制反转)),拦截器,静态代理和动态代理(Spring AOP))

    1.方法的静态和动态调用: struts.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCT ...

随机推荐

  1. Appium获取元素坐标

    文章转自:https://www.cnblogs.com/lfr0123/p/13686769.html appium做app自动化测试过程中,有时需要获取控件元素的坐标进行滑动操作.appium中提 ...

  2. C++ 手动创建二叉树,并实现前序、中序、后序、层次遍历

    二叉树的创建是个麻烦事,我的思路是:首先将一个普通的二叉树转化为满二叉树,其中的空节点用一些标识数据来代替,如此一来,就可以用数组索引来描述数据在二叉树的什么位置了. 比如,数组[2,4,3,1,5, ...

  3. Linux安装jdk之openjdk

    使用yum源 1.查看yum库中都有哪些jdk版本 yum search java|grep jdk 2.选择指定的版本安装,注意最后的 * 以及yum源安装的是openjdk,注意openjdk的区 ...

  4. python 小顶堆

    from heapq import *heap=[]for i in range(10,1,-1): heappush(heap,i)print(heap)print(heappop(heap))pr ...

  5. java中Atomic变量的实现原理是怎样的?

    转载自: Java3y https://www.zhihu.com/question/39130725/answer/1006948362 一.基础铺垫 首先我们来个例子: public class ...

  6. float高度塌陷和BFC

    开启BFC方式: 1.设置浮动float(副作用比较大,不推荐) 2.将元素设置为行内块元素 display:inline-block:(不推荐) 3.将元素的overlfow设置为非visible的 ...

  7. js原生判断数字类型

    js判断数字类型汇总最近在写代码的时候,有些逻辑需要判断数字类型,等用到的时候才发现自己了解的方法不太严密,然后就决心查资料汇总了解下有哪些方法比较严密 第一种:typeof + isNaN使用typ ...

  8. VirtualBox + Parrot

    安装环境:win8 1.官网下载virtualbox安装包,parrot kde sequrity镜像文件 2.用virtualbox创建新的虚拟机,内存4g,类型是linux debian 64,硬 ...

  9. 第二周集训队比赛wp

    Web1 直接截包改get为Host: Web2: 不一样的猪圈 普通的猪圈变种 NormalPwn 用IDA查看发现main下面有一个危险函数点进去发现/bin/sh 进main空格发现找cmman ...

  10. SDN第三次实验

    实验3:OpenFlow协议分析实践 实验目的 能够运用 wireshark 对 OpenFlow 协议数据交互过程进行抓包: 能够借助包解析工具,分析与解释 OpenFlow协议的数据包交互过程与机 ...