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 文件

  1. namespace java com.gemantic.analyse.thrift.index
  2. struct  NewsModel{
  3. :i32 id ;
  4. :string title;
  5. :string content;
  6. :string media_from;
  7. :string author;
  8. }
  9. service IndexNewsOperatorServices {
  10. bool indexNews(:NewsModel indexNews),
  11. bool deleteArtificiallyNews(:i32 id )
  12. }
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

  1. package com.gemantic.analyse.thrift.index;
  2. import java.net.InetSocketAddress;
  3. import org.apache.thrift.protocol.TBinaryProtocol;
  4. import org.apache.thrift.server.TServer;
  5. import org.apache.thrift.server.TThreadPoolServer;
  6. import org.apache.thrift.server.TThreadPoolServer.Args;
  7. import org.apache.thrift.transport.TServerSocket;
  8. import org.apache.thrift.transport.TServerTransport;
  9. import org.apache.thrift.transport.TTransportFactory;
  10. public class ThriftServerTest {
  11. /**
  12. * @param args
  13. */
  14. public static void main(String[] args) {
  15. // TODO Auto-generated method stub
  16. IndexNewsOperatorServices.Processor processor = new IndexNewsOperatorServices.Processor(new IndexNewsOperatorServicesImpl());
  17. try{
  18. TServerTransport serverTransport = new TServerSocket( new InetSocketAddress("0.0.0.0",));
  19. Args trArgs=new Args(serverTransport);
  20. trArgs.processor(processor);
  21. //使用二进制来编码应用层的数据
  22. trArgs.protocolFactory(new TBinaryProtocol.Factory(true, true));
  23. //使用普通的socket来传输数据
  24. trArgs.transportFactory(new TTransportFactory());
  25. TServer server = new TThreadPoolServer(trArgs);
  26. System.out.println("server begin ......................");
  27. server.serve();
  28. System.out.println("---------------------------------------");
  29. server.stop();
  30. }catch(Exception e){
  31. throw new RuntimeException("index thrift server start failed!!"+"/n"+e.getMessage());
  32. }
  33. }
  34. }
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

  1. package com.gemantic.analyse.thrift.index;
  2. import org.apache.thrift.TException;
  3. import org.apache.thrift.protocol.TBinaryProtocol;
  4. import org.apache.thrift.protocol.TProtocol;
  5. import org.apache.thrift.transport.TSocket;
  6. import org.apache.thrift.transport.TTransport;
  7. public class ThriftClientTest {
  8. /**
  9. * @param args
  10. * @throws TException
  11. */
  12. public static void main(String[] args) throws TException {
  13. // TODO Auto-generated method stub
  14. TTransport transport = new TSocket("10.0.0.41", );
  15. long start=System.currentTimeMillis();
  16. //      TTransport transport = new TSocket("218.11.178.110",9090);
  17. TProtocol protocol = new TBinaryProtocol(transport);
  18. IndexNewsOperatorServices.Client client=new IndexNewsOperatorServices.Client(protocol);
  19. transport.open();
  20. client.deleteArtificiallyNews();
  21. NewsModel newsModel=new NewsModel();
  22. newsModel.setId();
  23. newsModel.setTitle("this from java client");
  24. newsModel.setContent(" 世界杯比赛前,由于塞尔维亚和黑山突然宣布分裂,国际足联开会决定剔除塞黑,由世界上球迷最多的国家顶替,名额恰巧来到中国。举国上下一片欢腾,中国足协决定由“成世铎”(成龙+阎世铎)组队,进军世界杯。");
  25. newsModel.setAuthor("ddc");
  26. newsModel.setMedia_from("新华08");
  27. client.indexNews(newsModel);
  28. transport.close();
  29. System.out.println((System.currentTimeMillis()-start));
  30. System.out.println("client sucess!");
  31. }
  32. }
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

  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. $protocol = new TBinaryProtocol($transport);
  21. $client= new IndexNewsOperatorServicesClient($protocol, $protocol);
  22. $obj = new NewsModel($data);
  23. $result = $client->indexNews($obj);
  24. $transport->close();
  25. ?>
<?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

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

  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. transport.Open();
  5. NewsModel model = new NewsModel();
  6. model.Author = "jww";
  7. model.Title = "title";
  8. model.Content = "client   Come   From   CSharp";
  9. model.Id = 1;
  10. client.deleteArtificiallyNews(123);
  11. 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));

五、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://www.aboutyun.com/thread-7139-1-1.html

走进 thrift server的更多相关文章

  1. Spark SQL Thrift Server 配置 Kerberos身份认证和权限管理

    转载请注明出处:http://www.cnblogs.com/xiaodf/ 之前的博客介绍了通过Kerberos + Sentry的方式实现了hive server2的身份认证和权限管理功能,本文主 ...

  2. 【原创】用python连接thrift Server 去执行sql的问题总汇

    场景:python和现有产品的结合和应用——python的前瞻性调研 环境:centos7 0.首先确保安装了python和pyhive,下面是连接代码: #!/usr/bin/env python ...

  3. hive12启动报错org.apache.thrift.server.TThreadPoolServer.<init>(Lorg/apache/thrift/server/TThreadPoolServer$Args;)

    执行如下命令启动hive服务:./bin/hive --service hiveserver,报如下错误: Starting Hive Thrift ServerException in thread ...

  4. spark thrift server configuration

    # MainApplicationProperties # --master yarn --deploy-mode client 下的配置, client 模式表示,driver 是在本地机器上跑的, ...

  5. Spark Thrift Server

    ThriftServer是一个JDBC/ODBC接口,用户可以通过JDBC/ODBC连接ThriftServer来访问SparkSQL的数据.ThriftServer在启动的时候,会启动了一个Spar ...

  6. spark sql thrift server

    ### create data ## cat ## echo "$(date ;echo ## cat }'";exit}' ..} do passwd) echo "$ ...

  7. 「Spark」Spark SQL Thrift Server运行方式

    Spark SQL可以使用JDBC/ODBC或命令行接口充当分布式查询引擎.这种模式,用户或者应用程序可以直接与Spark SQL交互,以运行SQL查询,无需编写任何代码. Spark SQL提供两种 ...

  8. Python实现Thrift Server

    近期在项目中存在跨编程语言协作的需求,使用到了Thrift.本文将记录用python实现Thrift服务端的方法. 环境准备 根据自身实际情况下载对应的Thrift编译器,比如我在Windows系统上 ...

  9. Thrift笔记(五)--Thrift server源码分析

    从(四)server代码跟进 public static void simple(MultiplicationService.Processor processor) { try { TServerT ...

随机推荐

  1. [转帖]谷歌宣称首次实现量子优越性,IBM“不服”,中国同行咋看?

    谷歌宣称首次实现量子优越性,IBM“不服”,中国同行咋看? 投递人 itwriter 发布于 2019-10-24 15:46 评论(7) 有306人阅读 原文链接 [收藏] « » https:// ...

  2. C++ 字符串处理类 ProcessString (包含常用字符串处理函数)

    ProcessString.h //Linux & C++11 #pragma once //包含系统头文件 #include <string> #include <sstr ...

  3. Linux基础-10-网络原理和基础设置

    1. 使用ifconfig命令来维护网络 1) ifconfig命令的功能:显示所有正在启动的网卡的详细信息或设定系统中网卡的IP地址. 2) 应用ifconfig命令设定网卡的IP地址: 例如:修改 ...

  4. 初始NLTK

    NLTK官网:链接 Natural Language Toolkit NLTK corpora and lexical resources such as WordNet, along with a ...

  5. Python中turtle库的使用

    Turtle图形库 Turtle库是Python内置的图形化模块,属于标准库之一,位于Python安装目录的lib文件夹下,常用函数有以下几种: 画笔控制函数 penup():抬起画笔: pendow ...

  6. C++中的构造函数与析构函数及组合类的调用

    // 构造函数与析构函数及类的组合 #include "stdafx.h"#include <iostream>using namespace std; //枚举enu ...

  7. netty--使用注意事项

  8. Luogu5285 [十二省联考2019] 骗分过样例

    题目分析: 观察前3个点,$361=19*19$,所以可以发现实际上就是快速幂,然后模数猜测是$998244353$,因为功能编号里面有这个数字,用费马小定理处理一下. $pts:12$ 观察第4个点 ...

  9. shell 学习笔记7-shell-函数

    一.函数 1.什么是shell函数 把相同程序段定义成函数,可以减少整个程序的代码量,提升开发效率 增加程序的可读性,易读性,提升管理效率 可以失效程序功能模块化,使程序具备可移植性 其实linux系 ...

  10. java 线程并发(生产者、消费者模式)

    线程并发协作(生产者/消费者模式) 多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型“生产者/消费者模式”. Ø 什么是生产者? 生产者指的是负责生产数 ...