什么是 Thrift润脸?
- Thrift 是 Facebook 開源的一款跨語言 RPC 框架,它通過 IDL(接口描述語言) 來定義 RPC 數(shù)據(jù)類型和接口成福,這些內(nèi)容被寫在以 .thrift 結(jié)尾的文件中敌蚜,然后通過編譯器來生成不同語言的代碼,以滿足跨語言的需要
Thrift 安裝
Mac系統(tǒng)
- 使用 brew 快速安裝
brew install thrift
Window 系統(tǒng)
- 下載 Thrift.exe:http://www.apache.org/dyn/closer.cgi?path=/thrift/0.11.0/thrift-0.11.0.exe
- 將下載的 exe 程序重命名為 thrift.exe摆碉,并放入一個文件夾(我這放入 D 盤 Thrift 文件夾下)
- 配置環(huán)境變量 Path,在最后加上 D:\Thrift;
- 執(zhí)行命令查看是否安裝成功
thrift -version
如何使用 IDL 描述接口
- 在使用 Thrift 之前脓豪,需要提供一個 .thrift 文件巷帝,其內(nèi)容是使用 IDL 描述的服務(wù)接口信息
struct User{
1: i32 id
2: string name
}
service UserService{
User getUser(1:i32 uid)
}
- 上面 user.thrift 定義了了一個數(shù)據(jù)類型 User 與業(yè)務(wù)接口 UserService。然后執(zhí)行下面命令使用 Thrift 編譯器生成 Java 文件
thrift -r -gen java user.thrift
可用數(shù)據(jù)類型
-
bool:布爾值扫夜,對應(yīng) Java 的 boolean
-
byte:8 位有符號整數(shù)楞泼,對應(yīng) Java 的 byte
-
i16:16 位有符號整數(shù),對應(yīng) Java 的 short
-
i32:32 位有符號整數(shù)笤闯,對應(yīng) Java 的 int
-
i64:64 位有符號整數(shù)堕阔,對應(yīng) Java 的 long
-
double:64 位浮點(diǎn)數(shù),對應(yīng) Java 的 double
-
string:文本或二進(jìn)制字符串颗味,對應(yīng) Java 的 String
-
struct:定義公共的對象超陆,在 Java 中是一個 JavaBean
-
list:對應(yīng) Java 的 ArrayList
-
set:對應(yīng) Java 的 HashSet
-
map:對應(yīng) Java 的 HashMap
-
exception:對應(yīng) Java 的 Exception
-
service:service 類型可以被繼承
-
enum:枚舉類型
Thrift 網(wǎng)絡(luò)棧
- 下圖為 Thrift 的網(wǎng)絡(luò)棧,包含了 Transport浦马、Protocol时呀、Processor 層和 Server/Client 層
Transport
-
Transport 為底層網(wǎng)絡(luò)數(shù)據(jù)讀寫傳輸數(shù)據(jù)的抽象層张漂,Thrift 提供了如下幾個常用的 Transport 實(shí)現(xiàn):
-
TSocket:該 Transport 使用阻塞 Sockert 來收發(fā)數(shù)據(jù)
-
TFramedTransport:以幀形式發(fā)送數(shù)據(jù),如果服務(wù)器使用 NIO 時就必須使用該 Transport
-
TMemoryTransp:使用內(nèi)存 I/O谨娜,內(nèi)部使用了 ByteArrayOutputStream
-
TZlibTransport: 使用 Zlib 壓縮傳輸?shù)臄?shù)據(jù)鹃锈,但 Java 中未實(shí)現(xiàn)
Protocol
-
Protocol 為數(shù)據(jù)傳輸協(xié)議層,即對傳輸后的數(shù)據(jù)序列化和反序列化瞧预,常用的協(xié)議有:
-
TBinaryProtocol:二進(jìn)制格式
-
TCompactProtocol:壓縮格式
-
TJSONProtocol:JSON 格式
-
TSimpleJSONProtocol:提供 JSON 只寫協(xié)議,生成的文件很容易通過腳本語言解析
-
TDebugProtocoal:生成 Text 格式仅政,常用語調(diào)試
Processor
- Processor 層對象由 Thrift 根據(jù)用戶 IDL 文件生成垢油,我們通常不能指定,該層主要有兩個功能:
- 從 Protocol 層讀取數(shù)據(jù)然后交給對應(yīng) Handler 處理
- 將 Handler 處理的結(jié)果發(fā)送給 Protocol 層
Server
- Thrift 提供的 Server 實(shí)現(xiàn)有:
-
TNonblockingServer:基于多線程圆丹,非阻塞 IO 的 Server 層實(shí)現(xiàn)滩愁,專用于處理大量并發(fā)請求
-
THsHaServer:半同步/半異步的服務(wù)器模型
-
TThreadPoolServer:基于多線程阻塞 IO 的 Server 層實(shí)現(xiàn),它消耗的系統(tǒng)資源比 TNonblockingServer 高辫封,但可以提供更高的吞吐量
-
TSimpleServer: 該實(shí)現(xiàn)主要是用于測試. 它只有一個線程,并且是阻塞 IO, 因此在同一時間只能處理一個連接
Thrift 快速入門
- 以上面 user.thrift 為例硝枉,執(zhí)行下面命令生成兩個類 User、UserService 倦微,將其拷貝到項(xiàng)目中(可能需要修改類中的包路徑)
thrift -r -gen java user.thrift
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.11.0</version>
</dependency>
- 編寫 UserService 業(yè)務(wù)實(shí)現(xiàn)類
public class UserServiceImpl implements UserService.Iface {
@Override
public User getUser(int uid) throws TException {
User user = new User(uid,"ly");
return user;
}
}
public class Server {
public static void main(String[] args) throws Exception {
// 業(yè)務(wù)處理器
TProcessor processorr = new UserService.Processor<UserService.Iface>(new UserServiceImpl());
// 設(shè)置服務(wù)器
TServerSocket serverSocket = new TServerSocket(8181);
// 傳輸協(xié)議為二進(jìn)制
TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory();
// 使用單線程阻塞 I/O 模型
TServer.Args simpleArgs = new TServer.Args(serverSocket).processor(processorr).protocolFactory(protocolFactory);
TServer server = new TSimpleServer(simpleArgs);
System.out.println("開啟Thrift服務(wù)器妻味,監(jiān)聽端口:8181");
server.serve();
}
}
public class Client {
public static void main(String[] args) throws Exception {
// 設(shè)置調(diào)用的服務(wù)地址-端口
TTransport tTransport = new TSocket("localhost", 8181);
// 使用二進(jìn)制協(xié)議
TProtocol protocol = new TBinaryProtocol(tTransport);
// 使用的接口
UserService.Client client = new UserService.Client(protocol);
// 打開 Socket
tTransport.open();
System.out.println(client.getUser(123));
tTransport.close();
}
}
- 測試:先運(yùn)行 Server,在運(yùn)行 Client 可看到下面輸出
User(id:123, name:ly)