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

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

參考文獻(xiàn):

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

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抄罕,一起剝皮案震驚了整個濱河市辟汰,隨后出現(xiàn)的幾起案子民褂,更是在濱河造成了極大的恐慌,老刑警劉巖中剩,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件候味,死亡現(xiàn)場離奇詭異,居然都是意外死亡洪灯,警方通過查閱死者的電腦和手機(jī)坎缭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人掏呼,你說我怎么就攤上這事坏快。” “怎么了哄尔?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵假消,是天一觀的道長。 經(jīng)常有香客問我岭接,道長富拗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任鸣戴,我火速辦了婚禮啃沪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窄锅。我一直安慰自己创千,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布入偷。 她就那樣靜靜地躺著追驴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪疏之。 梳的紋絲不亂的頭發(fā)上殿雪,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天,我揣著相機(jī)與錄音锋爪,去河邊找鬼丙曙。 笑死,一個胖子當(dāng)著我的面吹牛其骄,可吹牛的內(nèi)容都是我干的亏镰。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼拯爽,長吁一口氣:“原來是場噩夢啊……” “哼索抓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起毯炮,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤逼肯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后否副,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汉矿,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡崎坊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年备禀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡曲尸,死狀恐怖赋续,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情另患,我是刑警寧澤纽乱,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站昆箕,受9級特大地震影響鸦列,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鹏倘,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一薯嗤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧纤泵,春花似錦骆姐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至公荧,卻和暖如春带射,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背稚矿。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工庸诱, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人晤揣。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓桥爽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親昧识。 傳聞我的和親對象是個殘疾皇子钠四,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容