Apache Thrift研究

1.    背景介绍... 3

2.    研究成果... 3

2.1.     环境与依赖... 3

2.2.     安装步骤... 3

2.2.1.      libEvent安装... 3

2.2.2.      boost安装(略)... 4

2.2.3.      zlib安装(略)... 4

2.2.4.      thrift安装... 4

2.2.5.      thriftcpp测试... 4

2.2.6.      thriftphp测试... 4

2.3.     实战... 5

2.3.1.      目标... 5

2.3.2.      thrift脚本... 5

2.3.3.      keywordServer6

2.3.4.      keywordphp. 7

2.3.5.      测试... 8

3.    性能测试... 10

4.    存在的缺陷... 10

5.    近期案例... 11

 


 

1.  背景介绍

thrift属于facebook.com技术核心框架之一,使用不同开发语言开发的系统可以通过该框架实现彼此间的通讯,开发者只需编辑一份thrift脚本,即可自动获得其它开发语言的代码(比如 c++、java、 python、ruby、 c#、 haskell、 ocmal、 erlang、 cocoa、 php、 squeak)。

thrift侧重点是构建夸语言的可伸缩的服务,特点就是支持的语言多,同时提供了完整的rpc service framework,可以很方便的直接构建服务,不需要做太多其他的工作。服务端可以根据需要编译成simple | thread-pool | threaded | nonblocking等方式;

thrift支持多种协议格,Thrift的代码实现,有专门的TProtocol和TTransport抽象,相互配合,可以实现多种协议,方便集成各种传输方式,目前支持xml、json等。

使用了epool!

Apache软件基金会已将Thrift作为孵化器项目纳入其中。

thrift目前不支持Windows平台,不过有牛人已经在cygwin上编译调试通过了。

官方开发白皮书:http://incubator.apache.org/thrift/static/thrift-20070401.pdf

2.  研究成果

2.1. 环境与依赖

Ø        操作系统:CentOS 5.2

Ø        依赖:

 

Lib

URL

1

thrift-20080411p1.tar.gz

http://developers.facebook.com/thrif

2

libevent-1.4.8-stable.tar.gz

http://monkey.org/~provos/libevent/

3

boost-1.33.1

http://www.boost.org/libs/smart_ptr/smart_ptr.htm

4

zlib

http://www.zlib.net/

2.2. 安装步骤

2.2.1. libEvent安装

1、 下载:http://monkey.org/~provos/libevent/

2、 安装:

>tar –zxvf libevent-1.4.8-stable.tar.gz

>cd libevent-1.4.8-stable/

>./configure

>make

>make install

2.2.2. boost安装(略)

参考libEvent安装步骤;

2.2.3. zlib安装(略)

参考libEvent安装步骤;

2.2.4. thrift安装

1.        下载:http://developers.facebook.com/thrif

2.        安装:(注:这里忽略了java部分的编译,如果需要请先安装javacompiler)

>tar –zxvf thrift-20080411p1.tar.gz

>cd thrift-20080411p1.tar.gz

>./configure CXXFLAGS='-g -O2'--with-java=no

>make

>make install

2.2.5. thrift cpp测试

>cdthrift-20080411p1/test/cpp/

>make –fMakefile.thrift

启动服务:

>./ TestServer

启动选项包括:

[--port=<portnumber>] 服务端口号;

[--server-type=<server-type>]服务启动类型;

[--protocol-type=<protocol-type>]协议类型;

[--workers=<worker-count>]线程池线程数,仅在服务类型为ThreadPool时有用;

 

server-type=simple| thread-pool | threaded | nonblocking,默认为simple

protocol-type=binary | ascii | xml,默认为binary

启动客户端测试:

>./TestClient

2.2.6. thrift php测试

>cdthrift-20080411p1/test/php/

>make

启动服务:

>./ TestServer

安装php脚本(我是在windows上安装的,步骤如下)

1、  thrift-20080411p1/lib/php/src/目录下所有文件拷贝到随意目录下的thrift目录下,例如:d:/thriftlib/

2、  thrift-20080411p1/test/php/gen-php/目录下的所有文件拷贝到apache主目录下的thrift/gen-php目录下;

3、  apache配置文件中增加一行:SetEnv THRIFT_ROOT d:/thriftlib/

4、  重启apache

5、  修改TestClient.php中的hostport配置,指向Linux服务器上的TestServer

6、  访问http://localhost/thrift/TestClient.php即可看到测试结果;

2.3. 实战

2.3.1. 目标

实现从指定文本串中提取关键词的webservice,客户端使用php;

接口要求:

输入:字符串(string),返回关键词个数(int32)

输出:关键词列表(list),包含关键词与关键词权重值,发生错误时抛异常(错误号、错误信息)

注:该demo仅作为验证thrift工程用,并非真实实现关键词功能,输出数据为假造数据,另外,关键词lib的初始化、析构等需要自己在产生的server代码中手工编辑;

2.3.2. thrift脚本

创建thrift-20080411p1/keyword目录:

>mkdir keyword

>cd keyword

>vikeyword.thrift

struct SWord{

        1: string strWord,

        2: double dbQ

}

exception KeywordExceptions {

        1: i32 iErrorCode,

        2: string strError

}

service CKeyword{

        list<SWord> getKeyword(1: stringstrText, 2: i32 iCount) throws (1: KeywordExceptions e)

}

2.3.3. keyword Server

>mkdir cpp

>cd cpp

>vi Makefile

ifndef thrift_home

thrift_home=../..

endif #thrift_home

 

target: all

 

ifndef boost_home

boost_home=/usr/include/boost

endif #boost_home

target: all

 

include_paths =$(thrift_home)/lib/cpp/src /

              $(boost_home)

 

include_flags = $(patsubst%,-I%, $(include_paths))

 

# Tools

ifndef THRIFT

THRIFT =../../compiler/cpp/thrift

endif # THRIFT

 

CC     =g++

LD     = g++

 

# Compiler flags

DCFL  = -Wall -O3 -g -I./gen-cpp $(include_flags)-L$(thrift_home)/lib/cpp/.libs -lthrift -lthriftnb -levent

LFL   = -L$(thrift_home)/lib/cpp/.libs -lthrift -lthriftnb -levent

CCFL  = -Wall -O3 -I./gen-cpp $(include_flags)

CFL   = $(CCFL) $(LFL)

 

all: server

 

debug: server-debug

 

stubs: ../keyword.thrift

       $(THRIFT) --gen cpp ../keyword.thrift

 

server-debug: stubs

       g++ -o KeywordServer $(DCFL)./gen-cpp/CKeyword_server.skeleton.cpp ./gen-cpp/CKeyword.cpp ./gen-cpp/keyword_types.cpp./gen-cpp/keyword_constants.cpp

 

server: stubs

       g++ -o KeywordServer $(CFL)./gen-cpp/CKeyword_server.skeleton.cpp ./gen-cpp/CKeyword.cpp./gen-cpp/keyword_types.cpp ./gen-cpp/keyword_constants.cpp

 

clean:

       rm -fr *.o KeywordServer KeywordClient gen-cpp

#生产服务端程序KeywordServer

>make

2.3.4. keyword php

>cd ..

>mkdir php

>cd php

>vi Makefile

# Default target is everything

target: all

 

# Tools

THRIFT =../../compiler/cpp/thrift

 

all: normal inline

 

normal: stubs

 

inline: stubs-inline

 

stubs: ../keyword.thrift

       $(THRIFT) --phpl ../keyword.thrift

 

stubs-inline: ../keyword.thrift

       $(THRIFT) --phpi ../keyword.thrift

 

clean:

       $(RM) -r gen-php gen-phpi

#产生php脚本

>make

2.3.5. 测试

>vi TestKeywordClient.php

<?php

if (!isset($GEN_DIR)) {

  $GEN_DIR = 'gen-php';

}

$MODE = 'inline';

if (!isset($MODE)) {

  $MODE = 'normal';

}

 

/** Set the Thrift root */

//$GLOBALS['THRIFT_ROOT'] ='../../lib/php/src';

 

/** Include the Thrift base */

require_once$GLOBALS['THRIFT_ROOT'].'/Thrift.php';

 

/** Include the binary protocol*/

require_once$GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';

 

/** Include the socket layer */

require_once$GLOBALS['THRIFT_ROOT'].'/transport/TSocketPool.php';

 

/** Include the socket layer */

require_once$GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';

 

echo'==============================='."/n";

echo ' SAFE TO IGNORE THESE INTEST'."/n";

echo'==============================='."/n";

 

/** Include the generated code*/

require_once$GEN_DIR.'/CKeyword.php';

require_once $GEN_DIR.'/keyword_types.php';

 

echo'==============================='."/n";

echo ' END OF SAFE ERRORSSECTION'."/n";

echo'==============================='."/n/n";

 

$host = '10.10.10.99';

$port = 9090;

 

if ($argc > 1) {

  $host = $argv[0];

}

 

if ($argc > 2) {

  $host = $argv[1];

}

 

$hosts = array($host);

$socket = new TSocket($host,$port);

$socket = newTSocketPool($hosts, $port);

$socket->setDebug(TRUE);

 

if ($MODE == 'inline') {

  $transport = $socket;

  $testClient = new CKeywordClient($transport);

} else {

  $bufferedSocket = newTBufferedTransport($socket, 1024, 1024);

  $transport = $bufferedSocket;

  $protocol = new TBinaryProtocol($transport);

  $testClient = newThriftTestClient($protocol);

}

 

$transport->open();

$start = microtime(true);

 

/**

 * GETKEYWORD TEST

 */

print_r('functiongetKeyword($strText, $iCount)');

try {

       $strText = "这是一个测试关键词获取的字符串!";

       $iCount = 8;

  $array_keyword =$testClient->getKeyword($strText, $iCount);

  print_r('result:');

  var_dump($array_keyword);

} catch (KeywordExceptions $e){

  print_r(' caught KeywordExceptions'.$e->iErrorCode.': '.$e->strError."/n");

}

 

/**

 * Normal tests done.

 */

$stop = microtime(true);

$elp = round(1000*($stop -$start), 0);

print_r("Total time: $elpms/n");

 

$transport->close();

return;

 

?>

将./keyword/php/gen-phpi/目录下的所有文件拷贝到apache主目录下的thrift/gen-php目录下,注意,只能用gen-phpi目录下的文件,gen-php目录下的文件测试未通过,目前原因不明,不过可以肯定不是bug,与服务器类型选择有关;

在浏览器中浏览http://localhost/thrift/web/TestKeywordClient.php

测试完毕!

3.  性能测试

以keyword demo为例:

Ø        Amd Athlon(tm) 64 X2 Dual CoreProcessor 4200+ (2CPUs), ~2.2GHz / 2G内存

Ø        Php安装在window 2003 + php 5.2.5 + apache2.2.8;

Ø        使用LoadRuner工具测试http://localhost/thrift/web/TestKeywordClient.php的访问并发;

Ø        linux为虚拟机(且与windows在一台机器上),该性能仅做参考:

 

平均并发:87

CPU:100%

 

该测试并未使用thrift提供的php_thrift_protocol加速扩展模块(仅在linux上可用),该模块可以加速二进制、对象等的传输速度;

4.  存在的缺陷

1、 生成的服务代码编译后,只能是控制台程序,需要自己改造成linux守护进程;

2、 提供的官方文档太简单,很多功能需要读代码;

3、 thrift脚本转cpp的帮助错误;

4、 自动产生的php脚本有bug,Ckeyword.php:: recv_getKeyword函数里面去掉版本判断语句:

if ($ver != 0x80010000) throw newTProtocolException('Bad version identifier: '.$ver,TProtocolException::BAD_VERSION);

5、 未提供官方性能报告;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值