1、About thrift
2、什麼是thrift,怎麼工做?
3、Thrift IDL
4、Thrift Demo
5、Thrift 協議棧 以及各層的使用(java 爲例)
6、與protocolbuffer的區別
1、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 調用 。
2、什麼是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++代碼
3、Thrift IDL
http://www.cnblogs.com/tianhuilove/archive/2011/09/05/2167669.html
http://wiki.apache.org/thrift/
http://wiki.apache.org/thrift/ThriftTypes
4、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 )
- }
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 {
-
-
- public static void main(String[] args) {
-
- 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));
-
- 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());
- }
- }
-
- }
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 {
-
-
- public static void main(String[] args) throws TException {
-
- TTransport transport = new TSocket("10.0.0.41", 9813);
- long start=System.currentTimeMillis();
- 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!");
- }
-
- }
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();
- ?>
<?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
-
-
- 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:
-
-
- transport = TSocket.TSocket('10.0.0.41', 9813)
-
-
- transport = TTransport.TBufferedTransport(transport)
-
-
- protocol = TBinaryProtocol.TBinaryProtocol(transport)
-
-
- client = Client(protocol)
-
-
- 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)
-
-
- transport.close()
- except Thrift.TException, tx:
- print '%s' % (tx.message)
#!/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));
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));
5、Thrift 協議棧 以及各層的使用(java 爲例)
一、model interface
服務的調用接口以及接口參數model、返回值model
二、Tprotocol 協議層
將數據(model)編碼 、解碼 。
三、Ttramsport 傳輸層
編碼後的數據傳輸(簡單socket、http)
五、Tserver
服務的Tserver類型,實現了幾種rpc調用(單線程、多線程、非阻塞IO)
6、與protocolbuffer的區別 http://liuchangit.com/development/346.html http://stackoverflow.com/questions/69316/biggest-differences-of-thrift-vs-protocol-buffers 區別: 一、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支持着更多的語言 。 二、Thrift supports ‘exceptions 。 thrift支持服務的異常 。 三、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簡單 。 四、Protobuf serialized objects are about 30% smaller then Thrift. Protocol Buffers在序列化/反序列化、傳輸上性能更優 。 五、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....) 六、And according to the wiki the Thrift runtime doesn't run on Windows. thrift 對有些語言在windows上不支持:C++ ..... 原文轉自: http://www.aboutyun.com/thread-7139-1-1.html