您的位置:首页 > 其它

thrift的使用介绍

2015-05-28 23:13 316 查看
一、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代码  


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 

Java代码  


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 

Java代码  


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代码  


<?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 

Python代码  


#!/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 

C#代码  


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++   ..... 

转自 :http://gemantic.iteye.com/blog/1199214
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: