聊聊Python用rpc实现分布式系统调用的那些事

简介:

通俗的讲rpc是什么?


rpc 一般俗称,远程过程调用,把本地的函数,放到远端去调用。

通常我们调用一个方法,譬如: sumadd(10, 20),sumadd方法的具体实现要么是用户自己定义,要么存在于该语言的库函数中,也就说在sumadd方法的代码实现在本地,它是一个本地调用!

“远程调用”意思就是:被调用方法的具体实现不在程序运行本地,而是在别的某个地方(分布到各个服务器),但是用起来像是在本地。


更多的关于RPC的内容可以到我的个人博客,blog.xiaorui.cc 看看。 


rpc远程调用原理 :


比如 A调用B提供的remoteAdd方法:


首先A与B之间建立一个TCP连接;


然后A把需要调用的方法名(这里是remoteAdd)以及方法参数(10, 20)序列化成字节流发送出去;


B接受A发送过来的字节流,然后反序列化得到目标方法名,方法参数,接着执行相应的方法调用(可能是localAdd)并把结果30返回;


A接受远程调用结果,然后do()


RPC框架也就是把上线说的具体的细节封装起来,给用户好用的API使用(提示:有些远程调用选择比较底层的socket协议,有些远程调用选择比较上层的HTTP协议);


一般rpc配合http协议的多点,也就是走http的多。 当然还是看应用,我曾经一共的rpc框架是基于zeromq的zerorpc。速度是挺快,server和client都有python的gevent支持,速度没道理慢。(有兴趣的,可以看看有关zerorpc的文章 http://rfyiamcool.blog.51cto.com/1030776/1254000 最少要比python本身的xml-rpc要快。 rpc over http(基于http的rpc)有两种协议,一种是xml-rpc ,还有一个是 json-rpc。


XML-RPC:XML Remote Procedure Call,即XML远程方法调用,利用http+xml封装进行RPC调用。基于http协议传输、XML作为信息编码格式。一个xml-rpc消息就是一个请求体为xml的http-post请求,服务端执行后也以xml格式编码返回。这个标准面前已经演变为下面的SOAP协议。可以理解SOAP是XML-RPC的高级版本。


JSON-RPC:JSON Remote Procedure Call,即JSON远程方法调用 。类似于XML-RPC,不同之处是使用JSON作为信息交换格式


下面是一个例子,很简单。我们是用python的rpc库SimpleXMLRPCServer 做的测试,创建rpc server,然后注册一些函数,供应别的客户端去调用。


原文:http://rfyiamcool.blog.51cto.com/1030776/1439824


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from SimpleXMLRPCServer  import  SimpleXMLRPCServer
原文:xiaorui.cc
def add(x,y):
     return  x+y
 
def subtract(x, y):
     return  x-y
 
def multiply(x, y):
     return  x*y
 
def divide(x, y):
     return  x /y
 
# A simple server with simple arithmetic functions
server = SimpleXMLRPCServer(( "localhost" , 8000))
print  "Listening on port 8000..."
server.register_multicall_functions()
server.register_function(add,  'add' )
server.register_function(subtract,  'subtract' )
server.register_function(multiply,  'multiply' )
server.register_function(divide,  'divide' )
server.serve_forever()


1
2
3
4
5
6
7
8
9
10
11
import  xmlrpclib
 
proxy = xmlrpclib.ServerProxy( "http://localhost:8000/" )
multicall = xmlrpclib.MultiCall(proxy)
multicall.add(7,3)
multicall.subtract(7,3)
multicall.multiply(7,3)
multicall.divide(7,3)
result = multicall()
 
print  "7+3=%d, 7-3=%d, 7*3=%d, 7/3=%d"  % tuple(result)



rpc本来是单任务的,如果任务相对频繁,可以设置成多线程的默认,你不用在调用threading模块什么的,直接引用 。


1
class  AsyncXMLRPCServer(SocketServer.ThreadingMixIn,SimpleXMLRPCServer):  pass

然后rpc初始化的方法换成。


1
server  =  AsyncXMLRPCServer(('',  1111 ), SimpleXMLRPCRequestHandler)


这里再说下,和xmlrpc相似的jsonrpc,貌似现在用xmlrpc的,要比jsonrpc的多点。  有时候到国外的it论坛看帖子,xmlrpc用的交多点。其实现在较大的公司,一般干脆直接自己实现了rpc框架,像淘宝Dubbo(朋友有搞过,搞了半天,没有对接成接口,说是有难度,不明觉厉!),百度的xxx(忘名字了)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import  jsonrpc
server  =  jsonrpc.Server(jsonrpc.JsonRpc20(), jsonrpc.TransportTcpIp(addr = ( "127.0.0.1" 31415 ), logfunc = jsonrpc.log_file( "myrpc.log" )))
#原文:xiaorui.cc
# 注册一个函数方法
def  echo(s):
     return  s
 
def  search(number = None , last_name = None , first_name = None ):
     sql_where  =  []
     sql_vars   =  []
     if  number  is  not  None :
         sql_where.append( "number=%s" )
         sql_vars.append(number)
     if  last_name  is  not  None :
         sql_where.append( "last_name=%s" )
         sql_vars.append(last_name)
     if  first_name  is  not  None :
         sql_where.append( "first_name=%s" )
         sql_vars.append(first_name)
     sql_query  =  "SELECT id, last_name, first_name, number FROM mytable"
     if  sql_where:
         sql_query  + =  " WHERE"  +  " AND " .join(sql_where)
     cursor  =  ...
     cursor.execute(sql_query,  * sql_vars)
     return  cursor.fetchall()
 
server.register_function( echo )
server.register_function( search )
 
# start server
server.serve()


原文:http://rfyiamcool.blog.51cto.com/1030776/1439824


1
2
3
4
5
6
7
8
# 创建jsonrpc客户端
import  jsonrpc
server  =  jsonrpc.ServerProxy(jsonrpc.JsonRpc20(), jsonrpc.TransportTcpIp(addr = ( "127.0.0.1" 31415 )))
 
#调用远端的一个函数
result  =  server.echo( "hello world" )
 
found  =  server.search(last_name = 'Python' )


我做过一些个压力的测试,XMLRPCSERVER的开了async之后,每个连接特意堵塞5秒,他的并发在40个左右 。也就是每秒成功40个左右,剩下的还是在堵塞等待中。 其实他的瓶颈不是在于rpc的本身,是承载rpc的那个basehttpserver,太弱爆了。

wKiom1PIg-qhOXPZAAH7nZDKUJM508.jpg


接收请求,调用方法 !

wKioL1PIilzjVjTxAAX07GYu-No166.jpg


 现在开源社区这么发达,有不少人都根据rpc的协议,重写了承载rpc的web服务。  比如用flask,tornado,配合uwsgi,你猜咋招了。。。。如果不堵塞连接,那还可以,如果堵塞连接,uwsgi的废材特色就显出来了,以前有文章说过,uwsgi是prework,他会预先启动进程,官方都推荐要根据你的cpu核数或者超线程来开启进程,如果开的太多,你会发现,uwsgi他是驾驭不了那么多进程的。还是看我大tornado,用了@gen.engine之后。轻易飙到500的并发连接。 

(以上是我的吃饱又蛋疼测试,没听过谁会重复调用那么多的堵塞方法,自评 sx行为) 

不多说了,看flask实现xmlrpc服务端的代码,看了下flask xmlrpc的源码,实现的不难。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from  flask  import  Flask
from  flaskext.xmlrpc  import  XMLRPCHandler, Fault
 
app  =  Flask(__name__)
 
handler  =  XMLRPCHandler( 'api' )
handler.connect(app,  '/api' )
 
@handler .register
def  woca(name = "world" ):
     if  not  name:
         raise  Fault( "fuck...fuck" "fuck shencan!" )
     return  "Hello, %s!"  %  name
原文:xiaorui.cc
app.run()

 

对于每个连接的超时,有多种的方法,如果你用的是flask,tornado做web server,那就写个装饰器single起来,只是性能不好。 或者是前面挂一个nginx,然后做个client_header_timeout,client_body_timeout,proxy_connect_timeout(你懂的。),如果用的python自带的xml-rpc的话,需要引入socket。

1
2
import  socket
socket.setdefaulttimeout()


再说下rpc安全的问题。

至于安全方面,有兴趣就开个ssl,或者是在程序里面判断下client ip,反正配置都是统一下发的,你重载daemon的时候,也就知道该判断什么ip了。


原文:http://rfyiamcool.blog.51cto.com/1030776/1439824


我个人对于rpc的应用,更加的倾向于基本资源的获取和调用,毕竟单纯的用socket或者是mq,你在程序里面还要做一个解析过来的数据,然后根据过来的数据在做调用。 (alert: 我想触发 add() ,如果是rpc的话,我不用管,只是传过去就行了,到那时mq和socket就需要eval调用函数了),一些复杂的应用还是喜欢用面向资源的rest,也推荐大家用这个,靠谱的。  






 本文转自 rfyiamcool 51CTO博客,原文链接:http://blog.51cto.com/rfyiamcool/1439824,如需转载请自行联系原作者


相关文章
|
2月前
|
机器学习/深度学习 数据可视化 TensorFlow
使用Python实现深度学习模型的分布式训练
使用Python实现深度学习模型的分布式训练
195 73
|
1月前
|
分布式计算 DataWorks 数据处理
产品测评 | 上手分布式Python计算服务MaxFrame产品最佳实践
MaxFrame是阿里云自研的分布式计算框架,专为大数据处理设计,提供高效便捷的Python开发体验。其主要功能包括Python编程接口、直接利用MaxCompute资源、与MaxCompute Notebook集成及镜像管理功能。本文基于MaxFrame最佳实践,详细介绍了在DataWorks中使用MaxFrame创建数据源、PyODPS节点和MaxFrame会话的过程,并展示了如何通过MaxFrame实现分布式Pandas处理和大语言模型数据处理。测评反馈指出,虽然MaxFrame具备强大的数据处理能力,但在文档细节和新手友好性方面仍有改进空间。
|
1月前
|
数据采集 人工智能 分布式计算
🚀 MaxFrame 产品深度体验评测:Python 分布式计算的未来
在数据驱动的时代,大数据分析和AI模型训练对数据预处理的效率要求极高。传统的Pandas工具在小数据集下表现出色,但面对大规模数据时力不从心。阿里云推出的Python分布式计算框架MaxFrame,以“Pandas风格”为核心设计理念,旨在降低分布式计算门槛,同时支持超大规模数据处理。MaxFrame不仅保留了Pandas的操作习惯,还通过底层优化实现了高效的分布式调度、内存管理和容错机制,并深度集成阿里云大数据生态。本文将通过实践评测,全面解析MaxFrame的能力与价值,展示其在大数据和AI场景中的卓越表现。
59 4
🚀 MaxFrame 产品深度体验评测:Python 分布式计算的未来
|
1月前
|
人工智能 分布式计算 大数据
MaxFrame 产品评测:大数据与AI融合的Python分布式计算框架
MaxFrame是阿里云MaxCompute推出的自研Python分布式计算框架,支持大规模数据处理与AI应用。它提供类似Pandas的API,简化开发流程,并兼容多种机器学习库,加速模型训练前的数据准备。MaxFrame融合大数据和AI,提升效率、促进协作、增强创新能力。尽管初次配置稍显复杂,但其强大的功能集、性能优化及开放性使其成为现代企业与研究机构的理想选择。未来有望进一步简化使用门槛并加强社区建设。
78 7
|
1月前
|
SQL 分布式计算 数据处理
云产品评测|分布式Python计算服务MaxFrame | 在本地环境中使用MaxFrame + 基于MaxFrame实现大语言模型数据处理
本文基于官方文档,介绍了由浅入深的两个部分实操测试,包括在本地环境中使用MaxFrame & 基于MaxFrame实现大语言模型数据处理,对步骤有详细说明。体验下来对MaxCompute的感受是很不错的,值得尝试并使用!
53 1
|
1月前
|
SQL 分布式计算 DataWorks
MaxCompute MaxFrame评测 | 分布式Python计算服务MaxFrame(完整操作版)
在当今数字化迅猛发展的时代,数据信息的保存与分析对企业决策至关重要。MaxCompute MaxFrame是阿里云自研的分布式计算框架,支持Python编程接口、兼容Pandas接口并自动进行分布式计算。通过MaxCompute的海量计算资源,企业可以进行大规模数据处理、可视化数据分析及科学计算等任务。本文将详细介绍如何开通MaxCompute和DataWorks服务,并使用MaxFrame进行数据操作。包括创建项目、绑定数据源、编写PyODPS 3节点代码以及执行SQL查询等内容。最后,针对使用过程中遇到的问题提出反馈建议,帮助用户更好地理解和使用MaxFrame。
|
1月前
|
分布式计算 数据处理 MaxCompute
云产品评测|分布式Python计算服务MaxFrame
云产品评测|分布式Python计算服务MaxFrame
74 2
|
1月前
|
人工智能 分布式计算 数据处理
有奖评测,基于分布式 Python 计算服务 MaxFrame 进行数据处理
阿里云MaxCompute MaxFrame推出分布式Python计算服务MaxFrame评测活动,助力开发者高效完成大规模数据处理、可视化探索及ML/AI开发。活动时间为2024年12月17日至2025年1月31日,参与者需体验MaxFrame并发布评测文章,有机会赢取精美礼品。
|
2月前
|
人工智能 分布式计算 数据处理
云产品评测:MaxFrame — 分布式Python计算服务的最佳实践与体验
阿里云推出的MaxFrame是一款高性能分布式计算平台,专为大规模数据处理和AI应用设计。它提供了强大的Python编程接口,支持分布式Pandas操作,显著提升数据处理速度(3-5倍)。MaxFrame在大语言模型数据处理中表现出色,具备高效内存管理和任务调度能力。然而,在开通流程、API文档及功能集成度方面仍有改进空间。总体而言,MaxFrame在易用性和计算效率上具有明显优势,但在开放性和社区支持方面有待加强。
66 9
|
2月前
|
分布式计算 大数据 数据处理
技术评测:MaxCompute MaxFrame——阿里云自研分布式计算框架的Python编程接口
随着大数据和人工智能技术的发展,数据处理的需求日益增长。阿里云推出的MaxCompute MaxFrame(简称“MaxFrame”)是一个专为Python开发者设计的分布式计算框架,它不仅支持Python编程接口,还能直接利用MaxCompute的云原生大数据计算资源和服务。本文将通过一系列最佳实践测评,探讨MaxFrame在分布式Pandas处理以及大语言模型数据处理场景中的表现,并分析其在实际工作中的应用潜力。
115 2

热门文章

最新文章