thrift介绍与实践
1.Introduce
Thrift is a software library and set of code-generation tools developed at Facebook to expedite development and implementation of efficient and scalable backend services.
Its primary goal is to enable efficient and reliable communication across programming languages by abstracting the portions of each language that tend to require the most customization into a common library that is implemented in each language.
Specifically, Thrift allows developers to define data types and service interfaces in a single language-neutral file and generate all the necessary code to build RPC clients and servers.
A transparent, high-performance bridge across many programming languages
RPC service framework
C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml
Thrift was open sourced in April 2007 and entered the Apache Incubator in May, 2008.
2.Types
It also does not require that the developer write any code for object serialization or transport.
Thrift IDL (Interface Definition Language)
The base types supported by Thrift are:
bool A boolean value, true or false
byte A signed byte
i16 A 16-bit signed integer
i32 A 32-bit signed integer
i64 A 64-bit signed integer
double A 64-bit floating point number
string An encoding-agnostic text or binary string
Structs
struct Example {
1:i32 number=10,
2:i64 bigNumber,
3:double decimals,
4:string name="thrifty"
}
Containers
list<type>
set<type>
map<type1,type2>
Exceptions
Services
service StringCache {
void set(1:i32 key, 2:string value),
string get(1:i32 key) throws (1:KeyNotFound knf),
void delete(1:i32 key)
}
3.Transport
3.1Interface
TTransport
open Opens the tranpsort
close Closes the tranport
isOpen Indicates whether the transport is open
read Reads from the transport
write Writes to the transport
flush Forces any pending writes
TServerTransport
open Opens the transport
listen Begins listening for connections
accept Returns a new client transport
close Closes the transport
3.2Implementation
Tsocket
provides a common, simple interface to a TCP/IP stream socket.
TFileTransport
an abstraction of an on-disk file to a datastream.
Utilities
TBufferedTransport
TFramedTransport
TMemoryBuffer
4.Protocol
The Thrift protocol is self-delimiting without any framing and regardless of the encoding format.
Implementation
a space-efficient binary protocol which is used by most backend services
Essentially, it writes all data in a flat binary format. Integer types are converted to network byte order, strings are prepended with their byte length,and all message and field headers are written using the primitive integer serialization constructs. String names for fields are omitted when using generated code, field identifiers are sufficient.
5.Versioning
critical to enable staged rollouts of changes to deployed services
Versioning in Thrift is implemented via field identifiers.
struct Example {
1:i32 number=10,
2:i64 bigNumber,
3:double decimals,
4:string name="thrifty"
}
Isset
When an unexpected field is encountered, it can be safely ignored and discarded. When an expected field is not found, there must be some way to signal to the developer that it was not present.
Case Analysis
Protocol/Transport Versioning
6.Processors
6.1RPC Implementation
Tprocessor
interface TProcessor {
bool process(TProtocol in, TProtocol out)
throws TException
}
Generated Code
all the logic to handle RPC invocations via the process() call
TServer
Implementation Details
7.Facebook Thrift Services
Search
Logging
Mobile
Ads
8.Similar Systems
SOAP
XML-based. Designed for web services via HTTP, excessive XML parsing overhead.
CORBA Relatively comprehensive, debatably overdesigned and heavyweight. Comparably cumbersome software installation.
COM
Embraced mainly in Windows client softare. Not an entirely open solution.
Pillar
Lightweight and high-performance, but missing versioning and abstraction.
Protocol Buffers
Closed-source, owned by Google. Described in Sawzall paper.
9.Practise
thriftTest.thrift
/** * @author leign * * 2011-5-23 */public class ThriftTestClient {static final int port = 8011;public static void main(String[] args){try {TTransport transport = new TSocket("localhost", port);transport.open();TProtocol protocol = new TBinaryProtocol(transport);try {Client client = new Client(protocol);String result1 = client.getNameById(123L);String result2 = client.getNameById(124L);System.out.println("result1==="+result1);System.out.println("result2==="+result2);} catch (ThriftTestException e) {e.printStackTrace();}transport.close();} catch (TTransportException e) {e.printStackTrace();} catch (TException e) {e.printStackTrace();}}}