Apache Thrift 序列化和RPC框架

為什么需要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

/******************************************************************/

參考文獻:

1.http://www.thrift.pl/

2.http://thrift-tutorial.readthedocs.io/en/latest/intro.html

3.《THE PROGRAMMER'S GUIDE TO Apache Thrift》第一章

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容