thrift學習(一)

一、About  thrift   
二、什麼是thrift,怎麼工作? 
三、Thrift  IDL 
四、Thrift   Demo 
五、Thrift 協議棧 以及各層的使用(java 爲例) 
六、與protocolbuffer的區別 

一、About  thrift   
         thrift是一種可伸縮的跨語言服務的發展軟件框架。它結合了功能強大的軟件堆棧的代碼生成引擎,以建設服務,工作效率和無縫地與C + +,C#,Java,Python和PHP和Ruby結合。thrift是facebook開發的,我們現在把它作爲開源軟件使用。thrift允許你定義一個簡單的定義文件中的數據類型和服務接口。以作爲輸入文件,編譯器生成代碼用來方便地生成RPC客戶端和服務器通信的無縫跨編程語言(來自百度百科)。    
  >>>最初由facebook開發用做系統內個語言之間的RPC通信 。 
  >>>2007年由facebook貢獻到apache基金 ,現在是apache下的opensource之一 。 
  >>>支持多種語言之間的RPC方式的通信:php語言client可以構造一個對象,調用相應的服務方法來調用java語言的服務 ,跨越語言的C/S   rpc  調用 。 


二、什麼是thrift,怎麼工作? 

java  rmi的例子,代碼見附件,建立一個java rmi的流程  : 
  >>>定義一個服務調用接口 。 
  >>>server端:接口實現---impl的實例---註冊該服務實現(端口)---啓動服務。 
  >>>client端:通過ip、端口、服務名,得到服務,通過接口來調用 。 
  >>>rmi數據傳輸方式:java對象序列化 。 

Thrift  服務  
  >>>例同rmi ,需要定義通信接口、實現、註冊服務、綁定端口…… 
  >>>如何多種語言之間通信  ? 
  >>>數據傳輸走socket(多種語言均支持),數據再以特定的格式(String ),發送,接收方語言解析   。 
        Object --->  String --->  Object  。 

    問題:編碼、解析完全需要自己做 ,複雜的數據結構會編碼困難 . 


Thrift  服務 :thrift的中間編碼層 
  >>>java  Object ---> Thrift  Object ---> php  Object   
  >>> 定義thrift的文件 ,由thrift文件(IDL)生成 雙方語言的接口、model ,在生成的model以及接口中會有解碼編碼的代碼 。 
  >>>thrift   文件例子 
     thrift-0.7.0.exe   -r   -gen  java    TestThrift.thrift    生成java 代碼 
     thrift-0.7.0.exe   -r   -gen  php    TestThrift.thrift    生成php代碼 
     thrift-0.7.0.exe   -r   -gen  py       TestThrift.thrift    生成python代碼 
     thrift-0.7.0.exe   -r   -gen  as3     TestThrift.thrift    生成as3代碼 
     thrift-0.7.0.exe   -r   -gen  cpp     TestThrift.thrift    生成C++代碼 

三、Thrift  IDL 
                 
       http://www.cnblogs.com/tianhuilove/archive/2011/09/05/2167669.html 

       http://wiki.apache.org/thrift/ 
           
       http://wiki.apache.org/thrift/ThriftTypes 

四、Thrift   Demo 
Thrift  IDL 文件 
Java代碼  收藏代碼
  1. namespace java com.gemantic.analyse.thrift.index  
  2.   
  3. struct  NewsModel{  
  4. 1:i32 id ;  
  5. 2:string title;  
  6. 3:string content;  
  7. 4:string media_from;  
  8. 5:string author;  
  9. }  
  10.   
  11. service IndexNewsOperatorServices {  
  12. bool indexNews(1:NewsModel indexNews),  
  13. bool deleteArtificiallyNews(1:i32 id )  
  14. }  


java  server 
Java代碼  收藏代碼
  1. package com.gemantic.analyse.thrift.index;  
  2.   
  3. import java.net.InetSocketAddress;  
  4.   
  5. import org.apache.thrift.protocol.TBinaryProtocol;  
  6. import org.apache.thrift.server.TServer;  
  7. import org.apache.thrift.server.TThreadPoolServer;  
  8. import org.apache.thrift.server.TThreadPoolServer.Args;  
  9. import org.apache.thrift.transport.TServerSocket;  
  10. import org.apache.thrift.transport.TServerTransport;  
  11. import org.apache.thrift.transport.TTransportFactory;  
  12.   
  13. public class ThriftServerTest {  
  14.   
  15.     /** 
  16.      * @param args 
  17.      */  
  18.     public static void main(String[] args) {  
  19.         // TODO Auto-generated method stub  
  20.         IndexNewsOperatorServices.Processor processor = new IndexNewsOperatorServices.Processor(new IndexNewsOperatorServicesImpl());  
  21.         try{  
  22.             TServerTransport serverTransport = new TServerSocket( new InetSocketAddress("0.0.0.0",9813));  
  23.             Args trArgs=new Args(serverTransport);  
  24.             trArgs.processor(processor);  
  25.             //使用二進制來編碼應用層的數據  
  26.             trArgs.protocolFactory(new TBinaryProtocol.Factory(truetrue));  
  27.             //使用普通的socket來傳輸數據  
  28.             trArgs.transportFactory(new TTransportFactory());  
  29.             TServer server = new TThreadPoolServer(trArgs);  
  30.             System.out.println("server begin ......................");  
  31.             server.serve();  
  32.             System.out.println("---------------------------------------");  
  33.             server.stop();  
  34.         }catch(Exception e){  
  35.             throw new RuntimeException("index thrift server start failed!!"+"/n"+e.getMessage());  
  36.         }  
  37.     }  
  38.   
  39. }  


java client 
Java代碼  收藏代碼
  1. package com.gemantic.analyse.thrift.index;  
  2.   
  3. import org.apache.thrift.TException;  
  4. import org.apache.thrift.protocol.TBinaryProtocol;  
  5. import org.apache.thrift.protocol.TProtocol;  
  6. import org.apache.thrift.transport.TSocket;  
  7. import org.apache.thrift.transport.TTransport;  
  8.   
  9. public class ThriftClientTest {  
  10.   
  11.     /** 
  12.      * @param args 
  13.      * @throws TException  
  14.      */  
  15.     public static void main(String[] args) throws TException {  
  16.         // TODO Auto-generated method stub  
  17.         TTransport transport = new TSocket("10.0.0.41"9813);  
  18.         long start=System.currentTimeMillis();  
  19. //      TTransport transport = new TSocket("218.11.178.110",9090);  
  20.         TProtocol protocol = new TBinaryProtocol(transport);  
  21.         IndexNewsOperatorServices.Client client=new IndexNewsOperatorServices.Client(protocol);  
  22.         transport.open();  
  23.   
  24.           
  25.         client.deleteArtificiallyNews(123456);  
  26.         NewsModel newsModel=new NewsModel();  
  27.         newsModel.setId(789456);  
  28.         newsModel.setTitle("this from java client");  
  29.         newsModel.setContent(" 世界盃比賽前,由於塞爾維亞和黑山突然宣佈分裂,國際足聯開會決定剔除塞黑,由世界上球迷最多的國家頂替,名額恰巧來到中國。舉國上下一片歡騰,中國足協決定由“成世鐸”(成龍+閻世鐸)組隊,進軍世界盃。");  
  30.         newsModel.setAuthor("ddc");  
  31.         newsModel.setMedia_from("新華08");  
  32.         client.indexNews(newsModel);  
  33.         transport.close();  
  34.         System.out.println((System.currentTimeMillis()-start));  
  35.         System.out.println("client sucess!");  
  36.     }  
  37.   
  38. }  


php client 
Php代碼  收藏代碼
  1. <?php  
  2. $GLOBALS['THRIFT_ROOT'] = '/home/tjiang/demo/thrift/lib/php/src';  
  3. require_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';  
  4. require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';  
  5. require_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php';  
  6. require_once $GLOBALS['THRIFT_ROOT'].'/transport/THttpClient.php';  
  7. require_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';  
  8. include_once $GLOBALS['THRIFT_ROOT'].'/packages/TestThrift/TestThrift_types.php';  
  9. include_once $GLOBALS['THRIFT_ROOT'].'/packages/TestThrift/IndexNewsOperatorServices.php';  
  10. $data=array(  
  11. 'id'=>'1',  
  12. 'title'=>'demo-標題',  
  13. 'content'=>'demo-內容',  
  14. 'media_from'=>'hexun',  
  15. 'author'=>'xiaodi667'  
  16. );  
  17. $thrif_server_url = '10.0.0.41';  
  18. $transport = new TSocket($thrif_server_url, 9813);  
  19. $transport->open();  
  20.   
  21. $protocol = new TBinaryProtocol($transport);  
  22.   
  23. $clientnew IndexNewsOperatorServicesClient($protocol$protocol);  
  24. $obj = new NewsModel($data);  
  25. $result = $client->indexNews($obj);  
  26.   
  27. $transport->close();  
  28. ?>  


python client 
Python代碼  收藏代碼
  1. #!/usr/bin/env python  
  2.   
  3. #  
  4. # Licensed to the Apache Software Foundation (ASF) under one  
  5. # or more contributor license agreements. See the NOTICE file  
  6. # distributed with this work for additional information  
  7. # regarding copyright ownership. The ASF licenses this file  
  8. # to you under the Apache License, Version 2.0 (the  
  9. # "License"); you may not use this file except in compliance  
  10. # with the License. You may obtain a copy of the License at  
  11. #  
  12. #   http://www.apache.org/licenses/LICENSE-2.0  
  13. #  
  14. # Unless required by applicable law or agreed to in writing,  
  15. # software distributed under the License is distributed on an  
  16. # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY  
  17. # KIND, either express or implied. See the License for the  
  18. # specific language governing permissions and limitations  
  19. # under the License.  
  20. #  
  21.   
  22. import sys  
  23.   
  24. from TestThrift.ttypes import NewsModel  
  25. from TestThrift.IndexNewsOperatorServices import Client  
  26.   
  27. from thrift import Thrift  
  28. from thrift.transport import TSocket  
  29. from thrift.transport import TTransport  
  30. from thrift.protocol import TBinaryProtocol  
  31.   
  32. try:  
  33.   
  34.   # Make socket  
  35.   transport = TSocket.TSocket('10.0.0.41'9813)  
  36.   
  37.   # Buffering is critical. Raw sockets are very slow  
  38.   transport = TTransport.TBufferedTransport(transport)  
  39.   
  40.   # Wrap in a protocol  
  41.   protocol = TBinaryProtocol.TBinaryProtocol(transport)  
  42.   
  43.   # Create a client to use the protocol encoder  
  44.   client = Client(protocol)  
  45.   
  46.   # Connect!  
  47.   transport.open()  
  48.   
  49.   client.deleteArtificiallyNews(123)  
  50.     
  51.   newsModel=NewsModel()  
  52.   newsModel.id=123456  
  53.   newsModel.title="python Test"  
  54.   newsModel.content="client test  come from python";  
  55.   newsModel.media_from="xinhua08"  
  56.     
  57.   client.indexNews(newsModel)  
  58.     
  59.   #close  
  60.   transport.close()  
  61. except Thrift.TException, tx:  
  62.   print '%s' % (tx.message)  


Csharp client 
C#代碼  收藏代碼
  1. TTransport transport = new TSocket("10.0.0.41", 9813);  
  2. TProtocol protocol = new TBinaryProtocol(transport);  
  3. IndexNewsOperatorServices.Client client = new IndexNewsOperatorServices.Client(protocol);  
  4.   
  5. transport.Open();  
  6. NewsModel model = new NewsModel();  
  7. model.Author = "jww";  
  8. model.Title = "title";  
  9. model.Content = "client   Come   From   CSharp";  
  10. model.Id = 1;  
  11.   
  12. client.deleteArtificiallyNews(123);  
  13. Console.WriteLine(client.indexNews(model));  



五、Thrift 協議棧 以及各層的使用(java 爲例) 
 
1、model   interface 
       服務的調用接口以及接口參數model、返回值model 
2、Tprotocol    協議層 
         將數據(model)編碼 、解碼 。 
3、Ttramsport 傳輸層 
        編碼後的數據傳輸(簡單socket、http) 
5、Tserver 
        服務的Tserver類型,實現了幾種rpc調用(單線程、多線程、非阻塞IO) 

六、與protocolbuffer的區別 
http://liuchangit.com/development/346.html 
            
http://stackoverflow.com/questions/69316/biggest-differences-of-thrift-vs-protocol-buffers 

區別: 
1、Another important difference are the languages supported by default.    protobuf: Java, C++, Python    Thrift: Java, C++, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk, Ocaml 
支持語言不同,thrift支持着更多的語言 。 
2、Thrift supports ‘exceptions 。 
   thrift支持服務的異常 。 
3、Protocol Buffers much easier to read 。Protobuf API looks cleaner, though the generated classes are all packed as an inner classes which is not so nice. 
   Protocol Buffers 在文檔方面比thrift豐富,而且比thrift簡單 。 
4、Protobuf serialized objects are about 30% smaller then Thrift. 
   Protocol Buffers在序列化/反序列化、傳輸上性能更優 。 
5、RPC is another key difference. Thrift generates code to implement RPC clients and servers wheres Protocol Buffers seems mostly designed as a data-interchange format alone.  
    thrift提供了一套完整的rpc服務實現(多線程socket、非阻塞的socket....) 
6、And according to the wiki the Thrift runtime doesn't run on Windows. 

   thrift 對有些語言在windows上不支持:C++   ..... 

感謝:來自http://gemantic.iteye.com/blog/1199214

發佈了35 篇原創文章 · 獲贊 9 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章