為什么需要Thrift赊窥?
Imagine the situation, where you have lots of applications written in different languages. In most popular scenario these are internal applications that perform various tasks and were written by separate development teams. How you enable those applications to talk to each other? Sure, you may add some REST APIs. But in many cases – especially when you transfer binary data – this solution doesn’t provide acceptable performance or maintainability.
Thrift的定義:
Apache Thrift is an open source cross?language serialization and remote?procedure call (RPC) framework. With?support for over 20 programming?languages, Apache Thrift can play an?important role in many distributed?application solutions. As a serialization?platform Apache Thrift enables efficient?cross language storage and retrieval of a?wide range of data structures. As an RPC?framework, Apache Thrift enables rapid?development of complete cross language?services with little more than a few lines?of code.
IDL的定義:
An?interface description language?or?interface definition language(IDL), is a?specification language?used to describe a?software component's?application programming interface(API). IDLs describe an interface in a?language-independent?way, enabling communication between software components that do not share one language. For example, between those written in?C++and those written in?Java. ?IDLs are commonly used in?remote procedure call?software. In these cases the machines at either end of the?link?may be using different?operating systems?and computer languages. IDLs offer a bridge between the two different systems.
Thrift的原理:
First, let's have a look at Apache Thrift from developer's point of view. Main concept of this framework is a?service, which resembles classes that you know from object-oriented programming languages. Every service has?methods, which are defined in a familiar way, using various?data typesimplemented in Apache Thrift. The data types are mapped to their native counterparts in every language, so in case of simple ones, like int, they are mapped to integer in every language, but more complex, like set becomes, for example, array in PHP or HashSet in Java. The services are defined in so called Apache Thrift?document, in which you use?Interface Description Language (IDL)?syntax (if you want to learn details about this syntax head to theofficial documentation).
Then, from this file – using Apache Thrift compiler – you generate?server?and?client stubs. These pieces of code are calling Apache Thrift library and you use them to implement server and clients – it's like filling the blank spaces with the relevant code (i.e. creating objects, calling methods, etc.) to allow cross-communication between your applications. The code that you generate for both client and server is embedded in your application. It is illustrated in the following image:
Figure 1. Source: "Learning Apache Thrift", Krzysztof Rakowski, Packt Publishing, December 2015
Before we get to the example code, which will explain this concept, let's have a quick look at the architecture of Apache Thrift. It is illustrated with the following simple image:
Figure 2. Source: "Learning Apache Thrift", Krzysztof Rakowski, Packt Publishing, December 2015
Transport provides a way to read and write payload from and to the medium you use (most commonly – a network or a socket). Protocol is mostly independent of the transport used and is responsible for encoding and decoding the data, so it can be transmitted. Most popular protocols are: binary, compact (Thrift's own) or JSON. Processor is generated automatically by the Apache Thrift compiler.?These three layers are combined in server and client codes. When you want two applications to communicate with each other, you need to use the same set of transport and protocol for encoding and decoding the information.
Thrift例子:
1. Describing services with Apache Thrift IDL
Service interfaces are the basis for communications between clients and servers in Apache Thrift. Apache Thrift services are defined using an Interface Definition Language
(IDL) similar to C in its notation. IDL code is saved in plain text files with a “.thrift” extension.
/************** hello.thrift ******************/
service?HelloSvc?{ ? ? ? ? ? ? ? ? ? ? ? ? ? #A
string?hello_func() ? ? ? ? ? ? ? ? ?#B
}
/************** hello.thrift ******************/
This IDL file declares a single service interface called HelloSvc #A. HelloSvc has onefunction, hello_func(), which accepts no parameters and returns a string #B. To use this
interface in an RPC application we can compile it with the Apache Thrift IDL Compiler.The IDLCompiler will generate stub code for both clients using the interface and
servers implementingthe interface. In this example we will begin by using the compiler to generate Python stubs forthe HelloSvc.
/**************************************/
thrift --gen py hello.thrift
/*************************************/
2. Building a Python Server
/****************************** hello_server.py **************************/
import?sys
sys.path.append("gen-py")
from?hello?import?HelloSvc
from?thrift.transport?import?TSocket
from?thrift.transport?import?TTransport
from?thrift.protocol?import?TBinaryProtocol
from?thrift.server?import?TServer
class?HelloHandler:
def?hello_func(self):
print("[Server]?Handling?client?request")
return?"Hello?from?the?python?server"
handler?=?HelloHandler()
proc?=?HelloSvc.Processor(handler)
trans_ep?=?TSocket.TServerSocket(port=9095)
trans_fac?=?TTransport.TBufferedTransportFactory()
proto_fac?=?TBinaryProtocol.TBinaryProtocolFactory()
server?=?TServer.TSimpleServer(proc,?trans_ep,?trans_fac,?proto_fac)
server.serve()
/****************************** hello_server.py **************************/
open service:
/************************************/
python hello_server.py
/************************************/
3.Building a Python Client
/*********************************** hello_client.py *********************/
import?sys
sys.path.append("gen-py")
from?hello?import?HelloSvc
from?thrift.transport?import?TSocket
from?thrift.transport?import?TTransport
from?thrift.protocol?import?TBinaryProtocol
trans_ep?=?TSocket.TSocket("localhost",?9095)
trans_buf?=?TTransport.TBufferedTransport(trans_ep)
proto?=?TBinaryProtocol.TBinaryProtocol(trans_buf)
client?=?HelloSvc.Client(proto)
trans_ep.open()
msg?=?client.hello_func()
print("[Client]?received:?%s"?%?msg)
/*********************************** hello_client.py *********************/
open client:
/*********************************/
python hello_client.py
/*********************************/
4. Building a Java Client
As a final example let’s put together a Java client for our service. Our first step is to generate
Java stubs for the service.
/****************************************/
thrift --gen java hello.thrift
/****************************************/
/*************************** HelloClient.java *********************/
import?org.apache.thrift.protocol.TBinaryProtocol;
import?org.apache.thrift.transport.TSocket;
import?org.apache.thrift.TException;
public?class?HelloClient?{
public?static?void?main(String[]?args)?throws?TException?{
TSocket?trans_ep?=?new?TSocket("localhost",?9095);
TBinaryProtocol?protocol?=?new?TBinaryProtocol(trans_ep);
HelloSvc.Client?client?=?new?HelloSvc.Client(protocol);
trans_ep.open();
String?str?=?client.hello_func();
System.out.println("[Client]?received:?"?+?str);
}
}
/*************************** HelloClient.java *********************/
complie and open client:
/******************************************************************/
javac -cp /usr/local/lib/libthrift-1.0.0.jar:?/usr/local/lib/slf4j-api-1.7.2.jar:?/usr/local/lib/slf4j-nop-1.7.2.jar?HelloClient.java gen-java/HelloSvc.java
java -cp /usr/local/lib/libthrift-1.0.0.jar:/usr/local/lib/slf4j-api-1.7.2.jar:/usr/local/lib/slf4j-nop-1.7.2.jar:./gen-java:. ??HelloClient
/******************************************************************/
參考文獻(xiàn):
2.http://thrift-tutorial.readthedocs.io/en/latest/intro.html
3.《THE PROGRAMMER'S GUIDE TO Apache Thrift》第一章