RPC 全称 Remote Procedure Call——远程过程调用。RPC技术简单说就是为了解决远程调用服务 的一种技术,使得调用者像调用本地服务一样方便透明
Thrift的定义
Thrift是一个轻量级、跨语言的RPC框架,主要用于各个服务之间的RPC通信,最初由Facebook于2007 年开发,2008年进入Apache开源项目。它通过自身的IDL中间语言, 并借助代码生成引擎生成各种主流语言的RPC服务端/客户端模板代码。Thrift支持多种不同的编程语言,包括C++, Java, Python, PHP, Ruby, Erlang, Haskell, C#, Cocoa, Javascript, Node.js, Smalltalk, OCaml, Golang等
Thrift的架构
Thrift技术栈分层从下向上分别为:传输层(Transport Layer)、协议层(Protocol Layer)、处理层(Processor Layer)和服务层(Server Layer)。
层级 | 作用 |
Transport Layer | 负责直接从网络中读取和写入数据,它定义了具体的网络传输协议,比如TCP/IP。 |
Protocol Layer | 协议层定义了数据传输格式,负责网络传输数据的序列化和反序列化; 比如说JSON、XML、二进制数据等。 |
Processor Layer | 处理层是由具体的IDL(接口描述语言)生成的,封装了具体的底层网 络传输和序列化方式,并委托给用户实现的Handler进行处理。 |
Server Layer | 整合上述组件,提供具体的网络IO模型(单线程/多线程/事件驱动),形成 最终的服务。 |
针对采用TCP/IP作为更底层的通信协议,整个通信过程如下图:
Thrift的特性
1、开发速度快: 通过编写RPC接口Thrift IDL文件,利用编译生成器自动生成服务端骨架(Skeletons)和客户端桩(Stubs)。 从而省去开发者自定义和维护接口编解码、消息传输、服务器多线程模型等基础工作。服务端:只需要按照服务骨架即接口,编写好具体的业务处理程序(Handler)即实现类即可。 客户端:只需要拷贝IDL定义好的客户端桩和服务对象,然后就像调用本地对象的方法一样调用远端服务。
2、接口维护简单:通过维护Thrift格式的IDL(接口描述语言)文件(注意写好注释),即可作为给Client使用的接口文档 使用,也自动生成接口代码,始终保持代码和文档的一致性。且Thrift协议可灵活支持接口的可扩展性。
3、学习成本低:因为其来自Google Protobuf开发团队,所以其IDL文件风格类似Google Protobuf,且更加易读易懂; 特别是RPC服务接口的风格就像写一个面向对象的Class一样简单。
4、跨语言支持:Thrift支持C++、 Java、Python、PHP、Ruby、Erlang、Perl、Haskell、C#、Cocoa、JavaScript、 Node.js、Smalltalk等多种语言,即可生成上述语言的服务器端和客户端程序。
5、稳定:Facebook中有广泛使用,国内包括百度、美团小米、和饿了么等公司都在广泛使用。
Thrift的协议
Thrift可以让用户选择客户端与服务端之间传输通信协议的类别,在传输协议上总体划分为文本(text)和二进制(binary)传输协议。为节约带宽,提高传输效率,一般情况下使用二进制类型的传输协议为多数, 有时还会使用基于文本类型的协议,这需要根据项目/产品中的实际需求。常用协议有以下几种:
- TBinaryProtocol:二进制编码格式进行数据传输
- TCompactProtocol:高效率的、密集的二进制编码格式进行数据传输
- TJSONProtocol: 使用JSON文本的数据编码协议进行数据传输
- TSimpleJSONProtocol:只提供JSON只写的协议,适用于通过脚本语言解析
Mac下Python跨语言调用测试
以Apache官网提供的测试代码为例子
1、安装HomeBrew
Mac下的包管理工具
# 安装homebrew
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
中途需要Press RETURN to continue
,输入系统密码等操作就完成了安装。
Homebrew安装成功后,会自动创建目录/usr/local/Cellar 来存放Homebrew安装的程序,并在 /usr/local/bin中创建符号链接。在终端就可以使用 brew 命令了。
2、安装Thirft
brew install thrift
3、编译器编译.thrift文件,生成python代码
下载IDL文件 生成python代码
# 首先使用pip命令安装thirft包
pip3 install thirft
# 生成python代码
thirft -gen py filename.thirft
4、编写服务端代码
# 核心代码
# func
handler = CalculatorHandler()
processor = Calculator.Processor(handler)
# transport server IP Port
transport = TSocket.TServerSocket(host='127.0.0.1', port=9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
print('Starting the server...')
server.serve()
print('done.')
5、编写Client端代码
# Make socket
transport = TSocket.TSocket('localhost', 9090)
# Buffering is critical. Raw sockets are very slow
transport = TTransport.TBufferedTransport(transport)
# Wrap in a protocol
protocol = TBinaryProtocol.TBinaryProtocol(transport)
# Create a client to use the protocol encoder
client = Calculator.Client(protocol)
# Connect!
transport.open()
# get server Ping func
res = client.ping()
print(res)
6、开启服务
# python3 client.py
# python3 server.py
然后我们的PRC架构就搭建完成了!
调用远程的方法
同样的,我们需要拿到IDL文件,生成python代码,然后编写Server端代码,就可以调用远程的方法了,主要的就是我们要获取到 IP,PORT,以及参数等信息就可以完成调用了!