亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

使用Thrift RPC編寫程序

2019-11-11 05:42:25
字體:
來源:轉載
供稿:網友

1. 概述

本文以C++語言為例介紹了thrift RPC的使用方法,包括對象序列化和反序列化,數據傳輸和信息交換等。

本文采用了一個示例進行說明,該示例主要完成傳輸(上報日志或者報表)功能,該示例會貫穿本文,內容涉及thrift定義,代碼生成,thrift類說明,client編寫方法,server編寫方法等。

關于Thrift架構分析,可參考:Thrift架構介紹。

關于Thrift文件編寫方法,可參考:Thrift使用指南。

關于Thrift內部實現原理,可參考:淺談Thrift內部實現原理。

2. 示例描述

假設我們要使用thrift RPC完成一個數據傳輸任務,數據格式和PRC接口用一個thrift文件描述,具體如下:

(1) book.thrift,用于描述書籍信息的thrift接口

1234567891011121314151617//book.thrift, namespacecpp example structBook_Info { 1: i32 book_id, 2: string book_name, 3: string book_author, 4:doublebook_price, 5: string book_publisher, }

(2) rpc.thrift,client向server傳輸數據(上報日志或者報表)的RPC接口

12345678910111213//rpc.thrift namespacecpp example include"book.thrift" service BookServlet { boolSender(1: list<book.Book_Info> books); onewayvoidSender2(1: list<book.Book_Info> books); }

說明:該thrift文件定義了一個service,它包含兩個接口,server端需要實現這兩個接口以對client提供服務。其中,第一個接口函數是阻塞式的,即要等待server返回值以后才能繼續,另外一個聲明為oneway類型(返回值為void),表明該函數是非阻塞式的,將數據發給server后不必等待返回結果,但使用該函數時,需要考慮server的承受能力,適度的調整發送頻率。

3. Thrift文件與生成的代碼對應關系

每個thrift文件會產生四個文件,分別為:${thrift_name}_constants.h,${thrift_name}_constants.cpp,${thrift_name}_types.h,${thrift_name}_types.cpp

對于含有service的thrift文件,會額外生成兩個文件,分別為:${service_name}.h,${service_name}.cpp

對于含有service的thrift文件,會生成一個可用的server樁:${service_name}._server.skeleton.cpp

對于本文中的例子,會產生以下文件:

book_constants.h book_constants.cpp

book_types.h book_types.cpp

rpc_constants.h rpc_constants.cpp

rpc_types.h rpc_types.cpp

BookServlet.h BookServlet.cpp

BookServlet_server.skeleton.cpp

4. Thrift類介紹

Thrift代碼包(位于thrift-0.6.1/lib/cpp/src)有以下幾個目錄:

concurrency:并發和時鐘管理方面的庫

processor:Processor相關類

protocal:Protocal相關類

transport:transport相關類

server:server相關類

4.1 Transport類(how is transmitted?)

負責數據傳輸,有以下幾個可用類:

TFileTransport:文件(日志)傳輸類,允許client將文件傳給server,允許server將收到的數據寫到文件中。

THttpTransport:采用Http傳輸協議進行數據傳輸

TSocket:采用TCP Socket進行數據傳輸

TZlibTransport:壓縮后對數據進行傳輸,或者將收到的數據解壓

下面幾個類主要是對上面幾個類地裝飾(采用了裝飾模式),以提高傳輸效率。

TBufferedTransport:對某個Transport對象操作的數據進行buffer,即從buffer中讀取數據進行傳輸,或者將數據直接寫入buffer

TFramedTransport:同TBufferedTransport類似,也會對相關數據進行buffer,同時,它支持定長數據發送和接收。

TMemoryBuffer:從一個緩沖區中讀寫數據

4.2 Protocol類(what is transmitted?)

負責數據編碼,主要有以下幾個可用類:

TBinaryProtocol:二進制編碼

TJSONProtocol:JSON編碼

TCompactProtocol:密集二進制編碼

TDebugProtocol:以用戶易讀的方式組織數據

4.3 Server類(providing service for clients)

TSimpleServer:簡單的單線程服務器,主要用于測試

TThreadPoolServer:使用標準阻塞式IO的多線程服務器

TNonblockingServer:使用非阻塞式IO的多線程服務器,TFramedTransport必須使用該類型的server

5. 對象序列化和反序列化

Thrift中的Protocol負責對數據進行編碼,因而可使用Protocol相關對象進行序列化和反序列化。

由于對象序列化和反序列化不設計傳輸相關的問題,所以,可使用TBinaryProtocol和TMemoryBuffer,具體如下:

(1) 使用thrift進行對象序列化

//對對象object進行序列化,保存到str中

123456789101112131415template<typenameType> voidObject2String(Type& object, string &str) {   shared_ptr<TMemoryBuffer> membuffer(newTMemoryBuffer());   shared_ptr<TProtocol> protocol(newTBinaryProtocol(membuffer));   object.write(protocol.get());   str.clear();   str = membuffer.getBufferAsString(); }

(2)使用thrift進行對象反序列化

123456789101112131415//對str中保存的對象進行反序列化,保存到object中 template<typenameType> voidString2Object(string& buffer, Type &object) {   shared_ptr<TMemoryBuffer> membuffer(newTMemoryBuffer(   reinterpret_cast<uint*>(buffer.data())));   shared_ptr<TProtocol> protocol(newTBinaryProtocol(membuffer));   object.read(protocol.get()); }

6. 編寫client和server

6.1 client端代碼編寫

Client編寫的方法分為以下幾個步驟:

(1) 定義TTransport,為你的client設置傳輸方式(如socket, http等)。

(2) 定義Protocal,使用裝飾模式(Decorator設計模式)封裝TTransport,為你的數據設置編碼格式(如二進制格式,JSON格式等)

(3) 實例化client對象,調用服務接口。

說明:如果用戶在thrift文件中定義了一個叫${server_name}的service,則會生成一個叫${server_name}Client的對象,比如,我給出的例子中,thrift會自動生成一個叫BookServletClient的類,Client端的代碼編寫如下:

123456789101112131415161718192021222324252627282930313233#include " gen-cpp/BookServlet.h" //一定要包含該頭文件 //其頭文件,其他using namespace ……. intmain(intargc, char** argv) {   shared_ptr<TTransport> socket(newTSocket("localhost", 9090));   shared_ptr<TTransport> transport(newTBufferedTransport(socket));   shared_ptr<TProtocol> protocol(newTBinaryProtocol(transport));   example::BookServletClient client(protocol); try{   transport->open();   vector<example::Book_Info> books;   …...   client.Sender(books);//RPC函數,調用serve端的該函數   transport->close(); }catch(TException &tx) {   printf("ERROR: %s/n", tx.what()); } }

6.2 Server端代碼編寫

(1) 定義一個TProcess,這個是thrift根據用戶定義的thrift文件自動生成的類

(2) 使用TServerTransport獲得一個TTransport

(3) 使用TTransportFactory,可選地將原始傳輸轉換為一個適合的應用傳輸(典型的是使用TBufferedTransportFactory)

(4) 使用TProtocolFactory,為TTransport創建一個輸入和輸出

(5) 創建TServer對象(單線程,可以使用TSimpleServer;對于多線程,用戶可使用TThreadPoolServer或者TNonblockingServer),調用它的server()函數。

說明:thrift會為每一個帶service的thrift文件生成一個簡單的server代碼(樁),在例子中,thrift會生成BookServlet_server.skeleton.cpp,用戶可以在這個文件基礎上實現自己的功能。

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475#include "gen-cpp/BookServlet.h" #include <protocol/TBinaryProtocol.h> #include <server/TSimpleServer.h> #include <transport/TServerSocket.h> #include <transport/TBufferTransports.h> usingnamespace ::apache::thrift; usingnamespace ::apache::thrift::protocol; usingnamespace ::apache::thrift::transport; usingnamespace ::apache::thrift::server; usingboost::shared_ptr; usingnamespace example; classBookServletHandler : virtualpublic BookServletIf { public: BookServletHandler() { // Your initialization goes here } //用戶需實現這個接口 boolSender(conststd::vector<example::Book_Info> & books) {   // Your implementation goes here   printf("Sender/n"); } //用戶需實現這個接口 voidSender2(conststd::vector<example::Book_Info> & books) {   // Your implementation goes here   printf("Sender2/n"); } }; intmain(intargc, char**argv) {   intport = 9090;   shared_ptr<BookServletHandler> handler(newBookServletHandler());   shared_ptr<TProcessor> processor(newBookServletProcessor(handler));   shared_ptr<TServerTransport> serverTransport(newTServerSocket(port));   shared_ptr<TTransportFactory> transportFactory(newTBufferedTransportFactory());   shared_ptr<TProtocolFactory> protocolFactory(newTBinaryProtocolFactory());   TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);   server.serve();   return0; }

7. 總結

至此,關于thrift框架的三篇文章已經全部完成,包括:

(1) Thrift框架介紹: Thrift框架介紹

(2) Thrift文件編寫方法: Thrift使用指南

(3) Thrift RPC使用方法:利用Thrift RPC編寫程序

與thrift類似的開源RPC框架還有google的protocal buffer,它雖然支持的語言比較少,但效率更高,因而受到越來越多的關注。

由于thrift開源時間很早,經受了時間的驗證,因而許多系統更愿意采用thrift,如Hadoop,Cassandra等。

附:thrift與protocal buffer比較

從上面的比較可以看出,thrift勝在“豐富的特性“上,而protocal buffer勝在“文檔化”非常好上。在具體實現上,它們非常類似,都是使用唯一整數標記字段域,這就使得增加和刪除字段與不會破壞已有的代碼。

它們的最大區別是thrift支持完整的client/server RPC框架,而protocal buffer只會產生接口,具體實現,還需要用戶做大量工作。

另外,從序列化性能上比較,Protocal Buffer要遠遠優于thrift,具體可參考:http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/?ca=drs-tp4608 。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久精品视频va| 亚洲高清一区二| 欧美精品videos另类日本| 国产日韩在线播放| 亚洲国产精品久久久久秋霞蜜臀| 国产精品91视频| 色妞欧美日韩在线| 麻豆乱码国产一区二区三区| 97久久国产精品| 亚洲va国产va天堂va久久| 久久69精品久久久久久久电影好| 中文字幕久热精品视频在线| 国产精品日本精品| 最新国产精品亚洲| 91久久中文字幕| 91香蕉嫩草神马影院在线观看| 日日骚久久av| 日韩欧美成人精品| 欧美刺激性大交免费视频| 欧美高清视频在线播放| 久久91精品国产91久久久| 国产视频久久久| 视频在线观看一区二区| 亚洲sss综合天堂久久| 色噜噜亚洲精品中文字幕| 欧美成人免费va影院高清| 欧美性猛交xxxx黑人猛交| 欧美国产乱视频| 成人疯狂猛交xxx| 欧美日韩国产综合视频在线观看中文| 日韩精品高清在线| 亚洲国产免费av| 2019精品视频| 亚洲精品天天看| 久久久国产精品视频| 日韩欧美国产骚| 亚洲精品xxxx| 国外成人在线直播| 国产精品观看在线亚洲人成网| 91精品视频播放| 超碰日本道色综合久久综合| 97国产精品视频人人做人人爱| 日韩免费在线播放| 91亚洲精品久久久久久久久久久久| 91精品国产91久久久久福利| 亚洲专区在线视频| 国产91色在线免费| 亚洲伊人久久大香线蕉av| 日韩精品高清在线观看| 91青草视频久久| 欧美日韩中文在线| 欧美区在线播放| 国产精品爱久久久久久久| 国产高清视频一区三区| 一个人www欧美| 国产精品久久久久久影视| 91中文字幕一区| 黄色一区二区在线| 亚洲电影成人av99爱色| 日韩精品极品视频| 成人97在线观看视频| 日韩精品亚洲精品| 亚洲激情久久久| 日韩av在线最新| 国产精品com| 久久久久久久久久久人体| 91免费高清视频| 欧美电影免费播放| 精品国产户外野外| 欧美激情视频三区| 国产精品video| 国产成人一区二区三区小说| 日本精品久久电影| 成人h片在线播放免费网站| 欧美一区二区三区精品电影| 久久免费成人精品视频| 久久久av一区| 性欧美xxxx视频在线观看| 日本高清视频精品| 国内免费精品永久在线视频| 亚洲一品av免费观看| 奇米4444一区二区三区| 成人av色在线观看| 欧美日韩一区二区精品| 少妇av一区二区三区| 亚洲图片制服诱惑| 欧美视频在线看| 国产精品爽黄69| 亚洲剧情一区二区| 成人淫片在线看| 亚洲高清在线观看| 另类专区欧美制服同性| 日本高清视频精品| 国产成人精品久久二区二区91| 久久久这里只有精品视频| 2023亚洲男人天堂| 中日韩美女免费视频网站在线观看| 91性高湖久久久久久久久_久久99| 亚洲第一精品福利| www.国产一区| 中文字幕精品影院| 疯狂做受xxxx高潮欧美日本| 亚洲综合色激情五月| 成人啪啪免费看| 亚洲国产精品福利| 18性欧美xxxⅹ性满足| 91综合免费在线| 91av免费观看91av精品在线| 中文字幕国内精品| 欧美网站在线观看| 日本成人在线视频网址| 日韩欧美精品在线观看| 亚洲国产私拍精品国模在线观看| 日本一区二区在线播放| 欧美中文字幕在线播放| 久久久久久久久久av| 欧美日韩aaaa| 国产精品都在这里| 久久网福利资源网站| 亚洲精品女av网站| 午夜精品久久久久久久久久久久| 亚洲美女在线看| 亚洲自拍偷拍在线| 亚洲女人天堂色在线7777| 精品成人国产在线观看男人呻吟| 亚洲成人在线网| 清纯唯美日韩制服另类| 欧美专区国产专区| 久久久久久久久久久成人| 久久久中文字幕| 国产精品免费观看在线| 中文字幕亚洲一区二区三区五十路| 亚洲天堂精品在线| 欧美极品少妇xxxxⅹ喷水| 国产精品久久77777| 韩剧1988在线观看免费完整版| 最近中文字幕mv在线一区二区三区四区| 亚洲缚视频在线观看| 亚洲精品www久久久| 国产精品h在线观看| 亚洲欧美一区二区三区四区| 国产亚洲精品美女久久久| xxxxx成人.com| 国产精品美女久久久免费| 欧美午夜宅男影院在线观看| 2019中文字幕在线免费观看| 久久久久久成人精品| 中文字幕国产日韩| 精品中文字幕视频| 国产精品久久久av久久久| 欧美成人免费小视频| 国产亚洲精品久久久久久777| 色婷婷综合成人av| 欧美精品一区在线播放| 国产精品一区二区三区久久久| 亚洲天堂开心观看| 亚洲国产精品va| 国产精品久久久久久久久| 久久久久五月天| 欧美性猛交99久久久久99按摩| 日韩av在线不卡| 色综合伊人色综合网站| 欧洲日本亚洲国产区| 精品国产一区二区三区久久久|