在Ubuntu上安装Thrift并调通一个例子 - 双子靓星 - 博客园
在Ubuntu上安装Thrift并调通一个例子
Thrift实际上是实现了C/S模式,通过代码生成工具将接口定义文件生成服务器端和客户端代码(可以为不同语言),从而实现服务端和客户端跨语言的支持。用户在Thirft描述文件中声明自己的服务,这些服务经过thrift编译后会生成相应语言的代码文件,然后用户实现服务(客户端调用服务,服务器端提服务)便可以了。其中protocol(协议层, 定义数据传输格式,可以为二进制或者XML等)和transport(传输层,定义数据传输方式,可以为TCP/IP传输,内存共享或者文件共享等)被用作运行时库。它支持多种数据传输格式、数据传输方式和服务模型等,直接指定调用即可。感谢好文:所以我的也算个实际命令性贴子了。0、准备篇因为要用C++,所以必须装Boost。其它语言的依赖看官方Wiki。下载Thrift:http://thrift.apache.org/download/ -> https://dist.apache.org/repos/dist/release/thrift/0.8.0/thrift-0.8.0.tar.gz下载Boost:http://www.boost.org/ -> http://sourceforge.net/projects/boost/files/boost/1.51.0/boost_1_51_0.tar.gz/download1、安装Boosttar -xvzf boost_1_51_0.tar.gzcd boost_1_51_0/./bootstrap.sh最终输出:
Building Boost.Build engine with toolset gcc... tools/build/v2/engine/bin.linuxx86_64/b2
Detecting Python version... 2.6
Detecting Python root... /usr
Unicode/ICU support
for
Boost.Regex?... not found.
Generating Boost.Build configuration in project-config.jam...
Bootstrapping is done. To build, run:
./b2
To adjust configuration, edit
'project-config.jam'
.
Further information:
- Command line help:
./b2 --help
- Getting started guide:
http:
//www.boost.org/more/getting_started/unix-variants.html
- Boost.Build documentation:
http:
//www.boost.org/boost-build2/doc/html/index.html
./b2 install 搞完了报了一点小错,暂时没管,也证明没事。因为失败的占成功的比例太小了。...failed updating 58 targets... ...skipped 12 targets...Boost装到了/usr/local/include 和 /usr/local/lib里。因为这没加配置参数,这是默认结果。2、安装Thrift
装Thrift之前的准备,依赖包提前装好:http://thrift.apache.org/docs/install/ubuntu/因为我准备按官方Wiki上搞C++的Server,Python的Client。所以:.
/configure
--with-cpp --with-boost=/usr/local
--with-python
--without-csharp --without-java --without-erlang --without-perl --without-php --without-php_extension --without-ruby --without-haskell --without-go
最终输出:thrift 0.8.0 Building code generators ..... : Building C++ Library ......... : yes Building C (GLib) Library .... : no Building Java Library ........ : no Building C# Library .......... : no Building Python Library ...... : yes Building Ruby Library ........ : no Building Haskell Library ..... : no Building Perl Library ........ : no Building PHP Library ......... : no Building Erlang Library ...... : no Building Go Library .......... : no Building TZlibTransport ...... : yes Building TNonblockingServer .. : yes Using Python ................. : /usr/bin/python If something is missing that you think should be present, please skim the output of configure to find the missing component. Details are present in config.log.makesudo make install3、试用例子我用的是Thrift的官方例子:http://thrift.apache.org/thrift --gen cpp UserProfile.thriftthrift --gen py UserProfile.thrift生成的文件在gen-cpp gen-py两个目录中。我用C++ Server端和Python的客户端。C++ Server相关:UserStorage_server.skeleton.cpp注释掉或者去掉 using namespace ;(位置大概17行左右) 。这个是Server端的Main函数。Client的main函数文件要自己写。C++编译选项:编译服务端:g++ -g -I/usr/local/include/thrift/ -L/usr/local/lib -lthrift UserProfile_constants.cpp UserProfile_types.cpp UserStorage.cpp UserStorage_server.skeleton.cpp -o server -DHAVE_NETINET_IN_H
编译客户端:g++ -g -I/usr/local/include/thrift/ -L/usr/local/lib -lthrift -lm -pthread -lz -lrt -lssl UserProfile_constants.cpp UserProfile_types.cpp UserStorage.cpp client.cpp -o client -DHAVE_NETINET_IN_H然后直接运行./server即顺。程序运行时加载共享库出现的错误时如下解决:"error while loading shared libraries: xxxx: cannot open shared object file: No such file or directory"
解决步骤:
1、使用find命令查找缺失的xxxx共享库文件所在位置。参考:#find 目录 -name "xxxx*"
2、将找到的目录位置写入 /etc/ld.so.conf 配置文件,这个文件记录了编译时使用的动态链接库的路径。
3、然后使用ldconfig命令,使配置生效。我的是在/usr/local/lib/里。
Python自己写的Client如下,运行即可:import sys import pprint from urlparse import urlparse from thrift.transport import TTransport from thrift.transport import TSocket from thrift.transport import THttpClient from thrift.protocol import TBinaryProtocol import UserStorage from ttypes import * up = UserProfile(uid=1, name="Test User", blurb="Thrift is great") # Talk to a server via TCP sockets, using a binary protocol transport = TSocket.TSocket("localhost", 9090) transport.open() protocol = TBinaryProtocol.TBinaryProtocol(transport) # Use the service we already defined service = UserStorage.Client(protocol) service.store(up)
运行Python出错,主要是加环境变量和改代码,这个贴子讲的挺好。http://www.cnblogs.com/dkblog/archive/2011/09/09/2172136.html我做了:export PYTHONPATH=/usr/lib/python2.6/site-packages4、Tutorial中的例子,另一个例子cd {THRIFTHOME}/thrift-0.8.0/tutorialthrift --gen cpp shared.thriftthrift --gen cpp tutorial.thrift搞完以后,gen-cpp中的Makefile要改一下:BOOST_DIR = /usr/local/include/boost/ 后面加-DHAVE_NETINET_IN_H server: CppServer.cpp g++ -o CppServer -I${THRIFT_DIR} -I${BOOST_DIR} -I../gen-cpp -L${LIB_DIR} -lthrift CppServer.cpp ${GEN_SRC} -DHAVE_NETINET_IN_H client: CppClient.cpp g++ -o CppClient -I${THRIFT_DIR} -I${BOOST_DIR} -I../gen-cpp -L${LIB_DIR} -lthrift CppClient.cpp ${GEN_SRC} -DHAVE_NETINET_IN_HServer和Client都起来就行。Client输出如下:
cpp$ ./CppClient ping() 1+1=2 InvalidOperation: Cannot divide by 0 15-10=5 Check log: 5杂记:
Client直接向Server发消息,那怎么从Server端拿回Response呢?这个例子已经显示了。Thrift中如此定义这个函数的:
i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),Client中这样就可以把Server的返回值拿回来了。
int32_t quotient = client.calculate(1, work);