走進 thrift server

thrift的使用介紹php

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 文件
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. }  
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代碼   收藏代碼
  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(true, true));  
  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. }  
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代碼   收藏代碼
  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. }  
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代碼   收藏代碼
  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. ?>  
<?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代碼   收藏代碼
  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)  
#!/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#代碼   收藏代碼
  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));  
                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
相關文章
相關標籤/搜索