thrift使用和源碼分析
阿新 • • 發佈:2018-07-28
服務 tac tex exce hub oid 目錄 圖片 cli
1 前言
thrift的官方文檔比較差,很多細節沒有介紹清楚,比如require、optional和default字段的區別是什麽,為什麽字段前面要寫序號等,帶著這些疑問,我們需要閱讀生成的源碼來了解具體細節。另外thrift的非官方文檔可以參考這篇:http://diwakergupta.github.io/thrift-missing-guide
2 network stack
thrif的網絡棧在官網已經介紹的比較清楚了,分為4層,從下往上依次是:
- Transport。提供網絡IO的簡單抽象
- Protocol。用於編解碼,將底層的字節編碼成二進制、JSON等;Protocol層用於對模式編碼以及負責序列化
- Processor。封裝了從Protocol讀寫的功能,可以理解為用戶的業務邏輯所在地
- Server。代碼一個服務端,將Transport、Protocol、Processor整合起來,等待請求到來並處理
3 簡單使用
3.1 thrift安裝
thrift的安裝按照官網的教程或者網上其他教程來就行了,這裏安裝的是thrift的0.8.0版本, 安裝完後可以使用命令查看安裝的thrift版本
thrift -version
3.2 編寫IDL
創建文件mythrift.thrift,在裏面編寫如下內容
namespace java com.learn.learnthrift struct Stu { 1:i32 name = 13 2:required i32 age 3:optional i32 height = 23 } struct Teacher { 1:string name = "13" 2:required string age = "14" 3:optional string height = "15" } service MyService { void printStu(1:Stu stu, 2:Teacher teacher) void printStu2(1:Stu stu, 2:Teacher teacher) }
3.3 生成java代碼
運行命令,生成java代碼,然後將生成的代碼拷貝進項目即可使用,其中mythrift.thrift就是剛才我們編寫的IDL文件。運行命令後會在mythrift.thrift所在的目錄生成gen-javabean文件夾,其內容就是我們生成java文件
thrift --gen java:beans mythrift.thrift
生成的文件如下:
3.4 編寫代碼
將生成的代碼copy到項目中,其中紅框框起來的是thrift生成的文件,其他的是需要我們編寫的代碼
DemoClient.java
public class DemoClient { public static void main(String[] args) throws Exception{ // 創建Transport TTransport transport = new TSocket("localhost", 9090, 5000); //創建protocol TProtocol protocol = new TBinaryProtocol(transport); //創建客戶端 MyService.Client client = new MyService.Client(protocol); transport.open(); Stu stu = new Stu(); stu.setAge(23); Teacher teacher = new Teacher("jack", "32"); client.printStu(stu, teacher); transport.close(); } }
DemoServer.java
public class DemoServer {
public static void main(String[] args) throws Exception{
// 創建processor
TProcessor tProcessor = new MyService.Processor<MyService.Iface>(new MyServiceImpl());
//創建protocol
TProtocolFactory tProtocolFactory = new TBinaryProtocol.Factory();
// 創建transport, TServerSocket繼承自TTransport
TServerSocket tServerSocket = new TServerSocket(9090);
//創建server參數
TServer.Args tArgs = new TServer.Args(tServerSocket);
tArgs.processor(tProcessor);
tArgs.protocolFactory(tProtocolFactory);
// 創建TServer
TServer tServer = new TSimpleServer(tArgs);
tServer.serve();
}
}
MyServiceImpl.java
public class MyServiceImpl implements MyService.Iface {
@Override
public void printStu(Stu stu, Teacher teacher) throws TException {
System.out.println(stu);
System.out.println("name:" + stu.getName());
System.out.println("age:" + stu.getAge());
System.out.println("height:" + stu.getHeight());
System.out.println("nameset: " + stu.isSetName());
System.out.println("ageset: " + stu.isSetAge());
System.out.println("height: " + stu.isSetHeight());
}
@Override
public void printStu2(Stu stu, Teacher teacher) throws TException {
System.out.println("printStu2 : " + stu);
}
}
然後分別運行DemoServer和DemoClient就可以了,這就是簡單的RPC通信
4 源碼閱讀
thrift使用和源碼分析