thrift優缺點
優點
官網:
https://thrift.apache.org/Thrift是一個跨語言的服務部署架構,最初由Facebook于2007年開發,2008年進入Apache開源項目。
Thrift通過一個中間語言(IDL, 接口定義語言)來定義RPC的接口和資料類型,然後通過一個編譯器生成不同語言的代碼(目前支援C++,Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk和OCaml),并由生成的代碼負責RPC協定層和傳輸層的實作。
Thrift實際上是實作了C/S模式,通過代碼生成工具将接口定義檔案生成伺服器端和用戶端代碼(可以為不同語言),進而實作服務端和用戶端跨語言的支援。使用者在Thirft描述檔案中聲明自己的服務,這些服務經過編譯後會生成相應語言的代碼檔案,然後使用者實作服務(用戶端調用服務,伺服器端提服務)便可以了。其中protocol(協定層, 定義資料傳輸格式,可以為二進制或者XML等)和transport(傳輸層,定義資料傳輸方式,可以為TCP/IP傳輸,記憶體共享或者檔案共享等)被用作運作時庫。
Thrift支援二進制,壓縮格式,以及json格式資料的序列化和反序列化。這讓使用者可以更加靈活的選擇協定的具體形式。更完美的是,協定是可自由擴充的,新版本的協定,完全相容老的版本!
缺點
極其缺少文檔,隻能通過讀thrift代碼充分的使用thrift,洽洽這是一件有樂趣的事情。
性能
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SM5QGZ4kjZlNGOzIWY4ADOkRGN0EGNzUzYmFTY0ETY38CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.png)
在CompactProtocol情況下性能和ProtoBuffer相當,
BinaryProtocol情況下性能是ProtoBuffer的60%左右。
thrift檔案定義
namespace cpp example
struct Book_Info {
1: i32 book_id,
2: string book_name,
3: string book_author,
4: double book_price,
5: string book_publisher,
}
namespace cpp example
include "book.thrift"
service BookServlet {
bool Sender(1: list<book.Book_Info> books);
oneway void Sender2(1: list<book.Book_Info> books);
}
代碼生成
book.thrift
/usr/bin/thrift --gen cpp book.thrift
thrift會在gen-cpp下面生成對應的cpp檔案:
├── book_constants.cpp
├── book_constants.h
├── book_types.cpp
└── book_types.h
rpc.thrift
/usr/bin/thrift --gen cpp rpc.thrift
├── BookServlet.cpp
├── BookServlet.h
├── BookServlet_server.skeleton.cpp
├── rpc_constants.cpp
├── rpc_constants.h
├── rpc_types.cpp
└── rpc_types.h
client端代碼
#include "gen-cpp/BookServlet.h"
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/protocol/TBinaryProtocol.h>
using namespace apache::thrift;
using namespace apache::thrift::transport;
using namespace apache::thrift::protocol;
using namespace example;
int main(int argc, char** argv) {
boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
example::BookServletClient client(protocol);
try {
transport->open();
std::vector<Book_Info> books;
books.push_back(Book_Info());
Book_Info &t0 = *books.rbegin();
t0.book_name = "bookname0";
books.push_back(Book_Info());
Book_Info &t1 = *books.rbegin();
t1.book_name = "bookname1";
client.Sender(books);
transport->close();
} catch (TException &tx) {
printf("ERROR: %s\n", tx.what());
}
printf("the end\n");
return 0;
}
server端代碼
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include <iostream>
#include "gen-cpp/BookServlet.h"
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using namespace example;
class BookServletHandler : virtual public BookServletIf {
public:
BookServletHandler() {}
bool Sender(const std::vector<Book_Info> & books) {
typedef std::vector<Book_Info>::const_iterator Itr;
for (Itr i = books.begin(); i != books.end(); ++i) {
std::cout<<i->book_name<<std::endl;
}
}
void Sender2(const std::vector<Book_Info> & books) {
printf("Sender2\n");
}
};
int main(int argc, char **argv) {
boost::shared_ptr<BookServletHandler> handler(new BookServletHandler());
boost::shared_ptr<TProcessor> processor(new BookServletProcessor(handler));
boost::shared_ptr<TServerTransport> serverTransport(new TServerSocket(9090));
boost::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();
return 0;
}
編譯和運作
g++ client.cpp gen-cpp/book_constants.cpp gen-cpp/BookServlet.cpp gen-cpp/book_types.cpp -lthrift -o client
g++ server.cpp gen-cpp/book_constants.cpp gen-cpp/BookServlet.cpp gen-cpp/book_types.cpp -lthrift -o server