因为一些历史起因须要在不同服务器之间建设rpc通道,来满足不定时、不定量且数据量可能会大的函数须要。在简略比照了之后投向了thrift,尽管网上大佬们说thrift的文档做的很烂,但具体有多烂这个我也不晓得,可能根底需要来讲也不重要。
Q: 为什么抉择rpc而不是RESTful API的形式?
A:
资源粒度。RPC 就像本地办法调用,RESTful API 每一次增加接口都可能须要额定地组织凋谢接口的数据,这相当于在利用视图中再写了一次办法调用,而且它还须要保护开发接口的资源粒度、权限等;
流量耗费。RESTful API 在应用层应用 HTTP 协定,哪怕应用轻型、高效、传输效率高的 JSON 也会耗费较大的流量,而 RPC 传输既能够应用 TCP 也能够应用 UDP,而且协定个别应用二制度编码,大大降低了数据的大小,缩小流量耗费。
Thrift的网络栈构造:
上面两层的数据传输:
TTransport层
代表thrift的数据传输方式,thrift定义了如下几种罕用数据传输方式
TSocket
: 阻塞式socket;TFramedTransport
: 以frame为单位进行传输,非阻塞式服务中应用;TFileTransport
: 以文件模式进行传输;
TProtocol层
代表thrift客户端和服务端之间传输数据的协定,艰深来讲就是客户端和服务端之间传输数据的格局(例如json等),thrift定义了如下几种常见的格局
TBinaryProtocol
: 二进制格局;TCompactProtocol
: 压缩格局;TJSONProtocol
: JSON格局;TSimpleJSONProtocol
: 提供只写的JSON协定;
thrift反对的Server模型
thrift次要反对以下几种服务模型
TSimpleServer
: 简略的单线程服务模型,罕用于测试;TThreadPoolServer
: 多线程服务模型,应用规范的阻塞式IO;TNonBlockingServer
: 多线程服务模型,应用非阻塞式IO(须要应用TFramedTransport
数据传输方式);THsHaServer
:THsHa
引入了线程池去解决,其模型读写工作放到线程池去解决,Half-sync/Half-async
解决模式,Half-async
是在解决IO事件上(accept/read/write io),Half-sync
用于handler对rpc的同步解决;
thrift IDL文件
thrift IDL不反对无符号的数据类型,因为很多编程语言中不存在无符号类型,thrift反对以下几种根本的数据类型
byte
: 有符号字节i16
: 16位有符号整数i32
: 32位有符号整数i64
: 63位有符号整数double
: 64位浮点数string
: 字符串
此外thrift还反对以下容器类型:
list
: 一系列由T类型的数据组成的有序列表,元素能够反复;set
: 一系列由T类型的数据组成的无序汇合,元素不可反复;map
: 一个字典构造,Key为K类型,Value为V类型,相当于java中的HashMap;
应用python编写thrift客户端代码
执行thrift --gen py src/thrift/data.thrift
生成对应的python
代码,并引入到python工程当中,代码构造如下图所示
python客户端代码
# -*- coding:utf-8 -*-__author__ = 'kpzhang'from py.thrift.generated import PersonServicefrom py.thrift.generated import ttypesfrom thrift import Thriftfrom thrift.transport import TSocketfrom thrift.transport import TTransportfrom thrift.protocol import TCompactProtocolimport sysreload(sys)sys.setdefaultencoding('utf8')try: tSocket = TSocket.TSocket("localhost", 8899) tSocket.setTimeout(900) transport = TTransport.TFramedTransport(tSocket) protocol = TCompactProtocol.TCompactProtocol(transport) client = PersonService.Client(protocol) transport.open() person = client.getPersonByUsername("张三") print person.username print person.age print person.married print '---------------------' newPerson = ttypes.Person(); newPerson.username = "李四" newPerson.age = 30 newPerson.married = True client.savePerson(newPerson) transport.close()except Thrift.TException, tx: print '%s' % tx.message
参考:
thrift基本原理