記錄我的Thrift 入門學習
Thrift 入門學習記錄
參照著官網以及各位大神的文件總算了解了些thrift的入門知識,記錄了我第一次學習thrift的歷程,不是什麼經驗心得,只是分享記錄下自己的學習過程,如有錯誤,歡迎各位大大指正^_^
1、thrift是什麼
thrift允許定義一個簡單的定義檔案中的資料型別和服務介面,這個檔案就是IDL(Interface Definition Language)以作為輸入檔案,編譯器生成程式碼。簡單的說就是thrift定義了統一的檔案(物件或者結構體,服務介面),使用thrift的編譯器能夠生成對應語言的程式碼檔案。thrft之所以是跨語言的原意就是他通過語言無關的自定義語言來生成語言相關的程式碼。
2、thrift的基本資料型別以及對應關係
官網文件的說明如下 bool Boolean, one byte byte Signed byte i16 Signed 16-bit integer i32 Signed 32-bit integer i64 Signed 64-bit integer double 64-bit floating point value string String Map<t1,t2> Map from one type to another List<t1> Ordered list of one type Set<t1> Set of unique elements of one type
容器
注:容器包含的元素可以是任意的Thrift型別(包含structs, exception), 不能是service
3、結構體及異常(Structs and Exceptions)
Struct同C語言中struct類似. Thrift編譯工具將struct轉換為OO語言中的類.Exception語法和功能等同於struct, 用於宣告異常.。他們只存在語義上的差別, 比如定義一個RPC服務, 開發可能會宣告一個遠端方法, 並丟擲一個Exception
4、服務Services
等同於OOP中的定義一個interface. Thrift的編譯工具會以此生成介面的客戶端, 服務端
5、類型別名
Typedefs
同C/C++的typedef
typedef i32 MyInteger
typedef Tweet ReTweet
結尾可以沒有分號,可以為struct定義別名
6、名稱空間Namespaces
Thrift的名稱空間類似C++或者Java的包. 他們都提供了一套便捷的程式碼組織(或者說隔離)的方法.名稱空間可以避免型別定義中同名衝突的問題。因為每個語言都有自己的命名管理機制, Thrift允許你分別定義不同語言的命名習慣。
例如,java中可以使用namespace java com.demo.thrift
7、包含Includes
為了便於維護, 我們會把Thrift的定義分拆到多個檔案, 從而達到重用並提升定義的模組化, 結構化. Thrift允許include其他Thrift定義檔案。include預設從當前檔案所在目錄開始搜尋, 也可以增加-I引數搜尋指定目錄下的關聯路徑.被包含進來的物件, 以thrift檔名作為字首檔名稱必須使用雙引號, 對末尾分號不敏感
從第一個thrift demo入門
下載安裝thrift
1) apprach官網下載thrift以及thrift.jar,slf4j.Jar,記得將下載的jar包匯入專案
2) thrift可以在官網下載,windows下,可以直接使用thrift.exe
3) 進入cmd命令列模式,進入到存放thrift.exe的目錄
4) cmd命令列下執行thrift -version輸出版本號即為可以使用建立一個.thrift檔案
我的.thrift檔案為:namespace java com.demo.thrift //名稱空間 //在這裡我定義了一個叫 addStringService的服務, service AddStringService{ // 服務中有一個叫做addString的方法名,返回型別是string 包括兩個引數,引數型別均為string string addString(1:string str1,2:string str2) }
接下來在cmd命令列下執行
thrift -gen java <.thrift檔案的路徑>
會在thrift的存放目錄下生成gen-java 檔案,將裡面生成的java拷貝到專案相應位置即可
自動生成了1000多行程式碼真是可怕。
程式碼中包括了一個Iface介面,需要我們後面來自己實現。編寫剛剛生成檔案的實現類,實現剛剛生成檔案中的Iface介面
我的實現類如下:AddString.java
java package com.demo.thrift; import org.apache.thrift.TException; public class AddString implements AddStringService.Iface{ public String addString(String str1, String str2) throws TException { //將str1與str2合併為一個字串 return str1+str2; } }
server端的實現
這裡是我的server段程式碼
TestThriftServer.java
package com.demo.server; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TBinaryProtocol.Factory; import org.apache.thrift.server.TServer; import org.apache.thrift.server.TSimpleServer; import org.apache.thrift.transport.TServerSocket; import org.apache.thrift.transport.TServerTransport; import com.demo.thrift.AddString; import com.demo.thrift.AddStringService; import com.demo.thrift.AddStringService.Processor; public class TestThriftServer { public static void main(String[] args) { try { //設定伺服器的埠 TServerTransport serverTransport = new TServerSocket(9090); //設定二進位制協議接收工廠 Factory protocolFactory=new TBinaryProtocol.Factory(); //設定關聯業務 AddString strhandler = new AddString(); Processor<AddStringService.Iface> processor=new Processor<AddStringService.Iface>(strhandler); //單執行緒伺服器端 Server.Args simpleArgs = new TServer.Args(serverTransport); simpleArgs.processor(processor); simpleArgs.protocolFactory(protocolFactory); TServer server = new TSimpleServer(simpleArgs); System.out.println("服務開啟...埠9090"); server.serve(); } catch (Exception x) { x.printStackTrace(); } System.out.println("done."); } }
client端的實現
a)設定傳輸方式,此處我使用的是socket方式傳輸 b)設定協議,這裡的協議和服務端協議保持一致 c)例項化客戶端物件,使用哪個介面的Client d)客戶端呼叫關聯後的業務 我的client端程式碼 TestThriftClient.java
package com.demo.client; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import com.demo.thrift.AddStringService.Client; public class TestThriftClient { public static void main(String[] args) { try{ //設定呼叫的服務地址埠 TTransport transport=new TSocket("localhost",9090); //此處的協議和伺服器上設定的保持一致 TProtocol protocol=new TBinaryProtocol(transport); //使用的介面 Client client=new Client(protocol); //開啟socket transport.open(); String res=client.addString("abc", "123"); System.out.println(res); transport.close(); }catch(Exception e){ e.printStackTrace(); } } }
執行服務端程式碼與客戶端程式碼,看到客戶端打印出abc123,第一個demo構建成功
第一篇部落格,還不會調格式- -,見諒