Thrift从⼊门到精通
和君 heweilong@youzan.com
Definition
The Apache Thrift software framework, for
scalable cross-language services development,
combines a software stack with a code
generation engine to build services that work
efficiently and seamlessly between C++, Java,
Python, PHP, Ruby, Erlang, Perl, Haskell, C#,
Cocoa, JavaScript, Node.js, Smalltalk, OCaml
and Delphi and other languages.
Core Concepts
TType
TProtocol
TTransport
TProcessor
TServer
数据结构
Basic Types:bool、byte、i16、i32、i64、double、
string、enum(i32)
Containers:list<type>、set<type>、map<type1,type2>
Structs:A struct has a set of strongly typed fields, each
with a unique name identifier,
Fields:Struct或者Message中都可以包含0个或多个
Field,结尾都会有⼀个STOP标记
Messages:Thrift报⽂单元
Field
isSet,每个域都有对应的isSet⽅法判断是否赋值
每个域可以使⽤required或者optional关键字标识
必要性,不标识则为默认
optional标识或者默认的域如果没有赋值则不会被
序列化
数据结构-structs
/**
* Structs are the basic complex data
structures. They are comprised of fields
* which each have an integer identifier, a
type, a symbolic name, and an
* optional default value.
*
* Fields can be declared "optional", which
ensures they will not be included
* in the serialized output if they aren't set.
Note that this requires some
* manual management in some languages.
*/
struct Work {
1: i32 num1 = 0,
2: i32 num2,
3: Operation op,
4: optional string
comment,
}
接⼜描述语⾔-IDL
service <name> {
<returntype> <name>(<arguments>) [throws (<exceptions>)] ...
}
service Calculator extends shared.SharedService {



void ping(),



i32 add(1:i32 num1, 2:i32 num2),



i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),



oneway void zip()



}
Example
def main():
# 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()
client.ping()
print('ping()')
sum_ = client.add(1, 1)
try {
handler = new CalculatorHandler();
processor = new Calculator.Processor(handler);
TServerTransport serverTransport = new
TServerSocket(9090);
TServer server = new TSimpleServer(new
Args(serverTransport).processor(processor));
// Use this for a multithreaded server
// TServer server = new TThreadPoolServer(new
TThreadPoolServer.Args(serverTransport).processor(processo
r));
System.out.println("Starting the simple server...");
server.serve();
} catch (Exception e) {
e.printStackTrace();
}
TProtocol
Protocol是⼀个抽象的概念,官⽅提供
了多语⾔的多种实现,包括
TBinaryProtocol、
TCompactProtocol、
TJSONProtocol、
TMultiplexedProtocol等
TMessage
TMessage
MessageBegin
MessageEnd
Field
FieldStop
FieldBegin
FieldEnd
…
针对请求,Filed承载的
是请求参数,针对响应,
Filed承载的是返回结
果,Exception是以
Struct结构体来承载的
TBinaryProtocol
TMessage
Method Name(string)
Type(8) Field Id(16) Value(string)Length(32)
Field(string)
Type(8) Field Id(16)
Value
Type(8)
Key
Type(8)
Field(map)
Key Value ……
FieldStop
Sequence Id (32)
Method Name Length(32)
Size(32)
Version | Message Type(32)
TMessageType
TType
TBinaryProtocol-演⽰
CALL calculate REPLY calculate
TTransport
TTransport TServerTransport
accept
listen
close
read write
close open
flush
open
TTransport实现
BIO
TServerSocketTSocket
ServerSocketSocket
NIO
TNonblockingServerSocketTNonblockingSocket
ServerSocketChannelSocketChannel
TServer
TSimpleServer:单线程阻塞IO,同时只能接受⼀个客户端连接
TNonblockingServer:单线程⾮阻塞IO,同时可以接受多个客户端连
接,Messages are processed by the same thread that calls select()
THsHaServer:单IO线程多Worker线程⾮阻塞IO,It uses a single
thread for network I/O, and a separate pool of worker threads to
handle message processing
TThreadedSelectorServer:多IO线程多Worker线程⾮阻塞IO,
ThreadedSelectorServer allows you to have multiple threads for
network I/O
TThreadPoolServer:多线程阻塞IO
TFramedTransport
/**
* TFramedTransport is a buffered TTransport that ensures a fully read message
* every time by preceding messages with a 4-byte frame size.
*/
为了解决NIO半包问题,当服务端为⾮阻塞实现时,客户端必须使⽤TFramedTransport
Reactor模型
Reactor多线程模型就是将Handler中的IO操作和⾮
IO操作分开,操作IO的线程称为IO线程,⾮IO操作
的线程称为⼯作线程
Service Request
Service Client
TProtocol
TTransport
Service Handler
TProcessor
TProtocol
TTransport
Client Server
TServer
Workflow
Generated
Code
Workflow
缺点
只解决了跨语⾔RPC调⽤问题,不是完善的SOA
解决⽅案
跨语⾔的SOA架构只是看起来那么美
扩展
协议的扩展:Thrift本⾝的Protocol设计是⾮常灵
活的,可以很轻松的扩展协议并实现跨语⾔
服务端实现的扩展:服务端除开Thrift的官⽅实现
之外,也可以在Netty这种与协议⽆关的IO框架上
层实现
SOA配套设施的扩展:服务注册发现、容错、负载
均衡、断路器等基础设施都需要⾃⾏实现,并且复
杂度跟接⼊的语⾔数量相关
基于Proxy的扩展
PHP Thrift
Client
Java Thrift
Client
Node.js
Thrift Client
Local Proxy Local Proxy Local Proxy
PHP Thrift
Server
Java Thrift
Server
Node.js
Thrift Server
服务发现、容错、负载均衡、断路器都可以由Local
Proxy来实现,统⼀了编程语⾔,减少开销和复杂度
谢谢!

Thrfit从入门到精通