一、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 文件 
  
- namespace java com.gemantic.analyse.thrift.index
- struct NewsModel{
- 1:i32 id ;
- 2:string title;
- 3:string content;
- 4:string media_from;
- 5:string author;
- }
- service IndexNewsOperatorServices {
- bool indexNews( 1:NewsModel indexNews),
- bool deleteArtificiallyNews( 1:i32 id )
- }
    
    
    java  server 
  
- package com.gemantic.analyse.thrift.index;
- import java.net.InetSocketAddress;
- import org.apache.thrift.protocol.TBinaryProtocol;
- import org.apache.thrift.server.TServer;
- import org.apache.thrift.server.TThreadPoolServer;
- import org.apache.thrift.server.TThreadPoolServer.Args;
- import org.apache.thrift.transport.TServerSocket;
- import org.apache.thrift.transport.TServerTransport;
- import org.apache.thrift.transport.TTransportFactory;
- public class ThriftServerTest {
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- IndexNewsOperatorServices.Processor processor = new IndexNewsOperatorServices.Processor( new IndexNewsOperatorServicesImpl());
- try{
- TServerTransport serverTransport = new TServerSocket( new InetSocketAddress( "0.0.0.0", 9813));
- Args trArgs= new Args(serverTransport);
- trArgs.processor(processor);
- //使用二进制来编码应用层的数据
- trArgs.protocolFactory( new TBinaryProtocol.Factory( true, true));
- //使用普通的socket来传输数据
- trArgs.transportFactory( new TTransportFactory());
- TServer server = new TThreadPoolServer(trArgs);
- System.out.println( "server begin ......................");
- server.serve();
- System.out.println( "---------------------------------------");
- server.stop();
- } catch(Exception e){
- throw new RuntimeException( "index thrift server start failed!!"+ "/n"+e.getMessage());
- }
- }
- }
    
    
    java client 
  
- package com.gemantic.analyse.thrift.index;
- import org.apache.thrift.TException;
- import org.apache.thrift.protocol.TBinaryProtocol;
- import org.apache.thrift.protocol.TProtocol;
- import org.apache.thrift.transport.TSocket;
- import org.apache.thrift.transport.TTransport;
- public class ThriftClientTest {
- /**
- * @param args
- * @throws TException
- */
- public static void main(String[] args) throws TException {
- // TODO Auto-generated method stub
- TTransport transport = new TSocket( "10.0.0.41", 9813);
- long start=System.currentTimeMillis();
- // TTransport transport = new TSocket("218.11.178.110",9090);
- TProtocol protocol = new TBinaryProtocol(transport);
- IndexNewsOperatorServices.Client client= new IndexNewsOperatorServices.Client(protocol);
- transport.open();
- client.deleteArtificiallyNews( 123456);
- NewsModel newsModel= new NewsModel();
- newsModel.setId( 789456);
- newsModel.setTitle( "this from java client");
- newsModel.setContent( " 世界杯比赛前,由于塞尔维亚和黑山突然宣布分裂,国际足联开会决定剔除塞黑,由世界上球迷最多的国家顶替,名额恰巧来到中国。举国上下一片欢腾,中国足协决定由“成世铎”(成龙+阎世铎)组队,进军世界杯。");
- newsModel.setAuthor( "ddc");
- newsModel.setMedia_from( "新华08");
- client.indexNews(newsModel);
- transport.close();
- System.out.println((System.currentTimeMillis()-start));
- System.out.println( "client sucess!");
- }
- }
    
    
    php client 
  
- <?php
- $GLOBALS[ 'THRIFT_ROOT'] = '/home/tjiang/demo/thrift/lib/php/src';
- require_once $GLOBALS[ 'THRIFT_ROOT']. '/Thrift.php';
- require_once $GLOBALS[ 'THRIFT_ROOT']. '/protocol/TBinaryProtocol.php';
- require_once $GLOBALS[ 'THRIFT_ROOT']. '/transport/TSocket.php';
- require_once $GLOBALS[ 'THRIFT_ROOT']. '/transport/THttpClient.php';
- require_once $GLOBALS[ 'THRIFT_ROOT']. '/transport/TBufferedTransport.php';
- include_once $GLOBALS[ 'THRIFT_ROOT']. '/packages/TestThrift/TestThrift_types.php';
- include_once $GLOBALS[ 'THRIFT_ROOT']. '/packages/TestThrift/IndexNewsOperatorServices.php';
- $data= array(
- 'id'=> '1',
- 'title'=> 'demo-标题',
- 'content'=> 'demo-内容',
- 'media_from'=> 'hexun',
- 'author'=> 'xiaodi667'
- );
- $thrif_server_url = '10.0.0.41';
- $transport = new TSocket( $thrif_server_url, 9813);
- $transport->open();
- $protocol = new TBinaryProtocol( $transport);
- $client= new IndexNewsOperatorServicesClient( $protocol, $protocol);
- $obj = new NewsModel( $data);
- $result = $client->indexNews( $obj);
- $transport->close();
- ?>
    
    
    python client 
  
- #!/usr/bin/env python
- #
- # Licensed to the Apache Software Foundation (ASF) under one
- # or more contributor license agreements. See the NOTICE file
- # distributed with this work for additional information
- # regarding copyright ownership. The ASF licenses this file
- # to you under the Apache License, Version 2.0 (the
- # "License"); you may not use this file except in compliance
- # with the License. You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing,
- # software distributed under the License is distributed on an
- # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- # KIND, either express or implied. See the License for the
- # specific language governing permissions and limitations
- # under the License.
- #
- import sys
- from TestThrift.ttypes import NewsModel
- from TestThrift.IndexNewsOperatorServices import Client
- from thrift import Thrift
- from thrift.transport import TSocket
- from thrift.transport import TTransport
- from thrift.protocol import TBinaryProtocol
- try:
- # Make socket
- transport = TSocket.TSocket( '10.0.0.41', 9813)
- # Buffering is critical. Raw sockets are very slow
- transport = TTransport.TBufferedTransport(transport)
- # Wrap in a protocol
- protocol = TBinaryProtocol.TBinaryProtocol(transport)
- # Create a client to use the protocol encoder
- client = Client(protocol)
- # Connect!
- transport.open()
- client.deleteArtificiallyNews( 123)
- newsModel=NewsModel()
- newsModel.id= 123456
- newsModel.title= "python Test"
- newsModel.content= "client test come from python";
- newsModel.media_from= "xinhua08"
- client.indexNews(newsModel)
- #close
- transport.close()
- except Thrift.TException, tx:
- print '%s' % (tx.message)
    
    
    Csharp client 
  
- TTransport transport = new TSocket( "10.0.0.41", 9813);
- TProtocol protocol = new TBinaryProtocol(transport);
- IndexNewsOperatorServices.Client client = new IndexNewsOperatorServices.Client(protocol);
- transport.Open();
- NewsModel model = new NewsModel();
- model.Author = "jww";
- model.Title = "title";
- model.Content = "client Come From CSharp";
- model.Id = 1;
- client.deleteArtificiallyNews(123);
- 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++   ..... 
  


 
         
					 
					