编译thrift和使用
我使用的版本是thrift-0.6.1
解压以后,先看readme,其中说编译环境参考http://wiki.apache.org/thrift/ThriftRequirements,打开看:
Language requirements
以C++为例,先安装Boost和libevent,zlib是一个支持压缩的,以后再说,按照网站的指示安装就可以了,
- C++
- Boost 1.33.1+
- libevent (optional, to build the nonblocking server)
- zlib (optional)
- Java
- Java 1.5+
- Apache Ant
- Apache Ivy (recommended)
- Apache Commons Lang (recommended)
- SLF4J
- C#: Mono 1.2.4+ (and pkg-config to detect it) or Visual Studio 2005+
- Python 2.4+ (including header files for extension modules)
- PHP 5.0+ (optionally including header files for extension modules)
- Ruby 1.8+ (including header files for extension modules)
- Erlang R12 (R11 works but not recommended)
- Perl 5
- Bit::Vector
- Class::Accessor
我编译thrift使用的是:
./configure --prefix=/usr/local/ --disable-static --with-libevent=/usr/local
没有加--with-boost=/usr/local,因为我把boost放在/usr/include下了,所以能够找到
因为我公司服务器是RHEL4,版本相对较老,所以出现了很多问题:
-。找不到BOOST
因我我早先已经在其它地方安装了boost,所以
#ln -s <我的boost root path>/boost /usr/include/boost
二。undefined reference to `_Unwind_Resume'
因为编译器较老,所以需要加上-Wl,-Bdynamic -lgcc_s 这个参数就可以了,一开始我只是在thrift的根目录的Makefile文件中的相关FLAG标记中加入了,但还是报相同错误,后仔细查看了错误信息,发现得在<thrift>/compiler/cpp和<thrift>/lib/cpp中的Makefile中加入才行
三、在rhel4.8上安装thrift.0.8
由于gcc32无法编译0.8,所以要执行
# ./configure CXX=g++4
就可以了,(系统上得安装gcc4相关的rpm),
如果不这样,直接改MakeFile中CXX=g++4的话,执行过程中会报一个错:
unsupported hardcode properties
导致无法继续执行下去的。
使用java时,要编译thrift的java包
cd thrift-0.6.0/lib/java
ant
编译完成以后会在当前目录下出现一个libthrift.jar
把libthrift.jar拷贝到/usr/local/lib下(这个位置是因为在thrift的tutor中,java sample code的build.xml中指明了要在/usr/local/lib找到这个jar文件)。
然后把/usr/local/lib/libthrift.jar也加入到CLASSPATH中。
三。no class template named `tr1' in `std'
还是因为编译器老的原因,只有在gcc 4.3以后才加入了tr1,所以只能换成boost中的tr1,具体在头文件中加入
在<thrift>/lib/cpp/src/concurrency/ThreadManager.h 中改为
#include <boost/tr1/memory.hpp>
#include <boost/tr1/functional.hpp>
就行了
////////////////////////////////////
在MacOS中使用参考:
http://wiki.apache.org/thrift/ThriftUsageObjectiveC
/////////////////////////////////////////////////////////////
数据类型
* Base Types:基本类型 bool,byte,i16,i32,i64,double,string(UTF-8 编码)
* Struct:结构体类型
* Container:容器类型,即List、Set、Map
* Exception:异常类型
* Service: 定义对象的接口,和一系列方法一个server只允许定义一个接口服务。这样的话多个接口需要多个server。这样会带来资源的浪费。同意通过继承接口的方式。
协议
Thrift可以让你选择客户端与服务端之间传输通信协议的类别,在传输协议上总体上划分为文本(text)和二进制(binary)传输协议, 为节约带宽,提供传输效率,一般情况下使用二进制类型的传输协议为多数,但有时会还是会使用基于文本类型的协议,这需要根据项目/产品中的实际需求:
* TBinaryProtocol – 二进制编码格式进行数据传输。
* TCompactProtocol – 这种协议非常有效的,使用Variable-Length Quantity (VLQ) 编码对数据进行压缩。
* TJSONProtocol – 使用JSON的数据编码协议进行数据传输。
* TSimpleJSONProtocol – 这种节约只提供JSON只写的协议,适用于通过脚本语言解析
* TDebugProtocol – 在开发的过程中帮助开发人员调试用的,以文本的形式展现方便阅读。传输层
服务端类型
* TSocket- 使用堵塞式I/O进行传输,也是最常见的模式。
* TFramedTransport- 使用非阻塞方式,按块的大小,进行传输,类似于Java中的NIO。
* TFileTransport- 顾名思义按照文件的方式进程传输,虽然这种方式不提供Java的实现,但是实现起来非常简单。
* TMemoryTransport- 使用内存I/O,就好比Java中的ByteArrayOutputStream实现。
* TZlibTransport- 使用执行zlib压缩,不提供Java的实现。
* TSimpleServer - 单线程服务器端使用标准的堵塞式I/O。
* TThreadPoolServer - 多线程服务器端使用标准的堵塞式I/O。
* TNonblockingServer – 多线程服务器端使用非堵塞式I/O,并且实现了Java中的NIO通道。
当服务器端使用socket协议时,可以用simple|thread-pool|threaded|nonblocking等方式运行,从而获得更好的性能。
基本使用
thrift的类型有如下几种:
/**
* The first thing to know about are types. The available types in Thrift are:
*
* bool Boolean, one byte
* byte Signed byte
* i16 Signed 16-bit integer
* i32 Signed 32-bit integer
* i64 Signed 64-bit integer
* double 64-bit floating point value
* string String
* binary Blob (byte array)
* map<t1,t2> Map from one type to another
* list<t1> Ordered list of one type //对应C++中的vector<t1>
* set<t1> Set of unique elements of one type
*
* Did you also notice that Thrift supports C style comments?
*/
例子
编写角本service.thrift
/**
* This Thrift file can be included by other Thrift files that want to share
* these definitions.
*/
namespace cpp shared
//namespace java shared
//namespace perl shared
struct SharedStruct {
1: i32 key
2: string value
}//定义一个结构体
//定义一个服务
service SharedService {
SharedStruct getStruct(1: i32 key)
}
使用下面的语句,生成cpp骨架文件
thrift –r –gen cpp service.thrift
(生成php骨架文件: # thrift –r –gen php service.thrift )
生成7个文件,分别是由service.thrift脚本定义的类型文件四个,两个.h文件 (service_constants.h,service_types.h),两个对应的.cpp文件 (service_constants.cpp,service_types.cpp)。service_types对应的文件中,定义了对应的由 service.thrift脚本定义的类型。例如struct SharedStruct对应到一个类。另外三个文件分别是由service.thrift脚本中所定义的服务相关的文件,分别是 SharedService .h,SharedService .cpp,以及SharedService_server.skeleton.cpp 骨架文件,我们只需要修改SharedService_server.skeleton.cpp 骨架文件中相关的接口部分的逻辑,即可生成对应的服务。
///////////////////////////
进入cpp目录下,执行make命令,如果编译出错,第一个错误是/usr/local/include/thrift/protocol/TBinaryProtocol.tcc:147:35: error: there are no arguments to ‘htons’ that depend on a template parameter, so a declaration of ‘htons’ must be available则修改Makefile,加上编译选项 -DHAVE_NETINET_IN_Hserver: CppServer.cppg++ -DHAVE_NETINET_IN_H -o CppServer -I${THRIFT_DIR} -I${BOOST_DIR} -I../gen-cpp -L${LIB_DIR} -lthrift CppServer.cpp ${GEN_SRC}