ImageVerifierCode 换一换
格式:DOCX , 页数:21 ,大小:55.56KB ,
资源ID:5761540      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-5761540.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Thrift之TProcess类体系原理及源码详细解析Word文档格式.docx)为本站会员(b****2)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

Thrift之TProcess类体系原理及源码详细解析Word文档格式.docx

1、preWrite在处理和写响应之间调用postWrite在写响应之后调用asyncComplete当一个异步函数成功完成调用时调用handlerError如果处理函数抛出没有定义的异常就会调用此函数最后一个类就是TProcessorContextFreer类,这个类是一个帮助类,帮助生成的代码来释放上下文资源。第二节 基于框架生成的服务实例分析本节将对scribe服务器采用的服务实现进行详细分析。1 接口定义语言文件(IDL)(1)Facebook内部共用服务协议主要有两个文件,一个是在Thrift中定义,是用于Facebook内部的一些接口服务定义,这个不仅仅用于scribe服务器,可能还用

2、于Facebook内部其他系统,这个文件内容如下: 1 namespace java com.facebook.fb303 2 3 namespace cpp facebook.fb303 4 5 namespace perl Facebook.FB303 6 7 enum fb_status 8 9 DEAD = 0,10 11 STARTING = 1,12 13 ALIVE = 2,14 15 STOPPING = 3,16 17 STOPPED = 4,18 19 WARNING = 5,20 21 22 23 service FacebookService 24 25 string

3、getName(),26 27 string getVersion(),28 29 fb_status getStatus(),30 31 string getStatusDetails(),32 33 map getCounters(),34 35 i64 getCounter(1: string key),36 37 void setOption(1: string key, 2: string value),38 39 string getOption(1:40 41 map getOptions(),42 43 string getCpuProfile(1: i32 profileDu

4、rationInSec),44 45 i64 aliveSince(),46 47 oneway void reinitialize(),48 49 oneway void shutdown(),50 51 上面这个IDL文件定义了一个枚举类型用于表示服务的状态,还定义了一个名位FacebookService的服务,里面定义了各种操作,如获取服务状态的操作、得到计数的操作等等。下面我们来看看根据这个IDL文件生成的C+代码是什么样的一个架构。首先生成了一个基于上面服务定义的抽象类如下:class FacebookServiceIf public: virtual FacebookService

5、If() virtual void getName(std:string& _return) = 0; virtual void getVersion(std: virtual fb_status getStatus() = 0; virtual void getStatusDetails(std: virtual void getCounters(std:map & virtual int64_t getCounter(const std: key) = 0; virtual void setOption(const std: key, const std: value) = 0; virt

6、ual void getOption(std: _return, const std: virtual void getOptions(std:string, std:string virtual void getCpuProfile(std: _return, const int32_t profileDurationInSec) = 0; virtual int64_t aliveSince() = 0; virtual void reinitialize() = 0; virtual void shutdown() = 0;注意观察,除了这个类多了一个虚析构函数,其他函数就是IDL中定义

7、的。接着定义了类FacebookServiceNull,这个是上面那个抽象类的空实现(就是所有方法都没有做具体的事情),这样做的好处就是我们需要重写一些函数的时候只需要关注我们需要写的函数,而不是重写所有函数。接着又定义了封装每一个函数参数的相应类,就是一个函数的参数都用一个类来封装定义,函数的返回值也是这样处理。这样做的目的是统一远程调用的实现接口,因为传递参数都只需要这个封装类的对象就可以了。所以你会看到每一个服务里面定义的函数都有下面一组类的定义: 1 (1)class FacebookService_getName_args 3 (2)class FacebookService_get

8、Name_pargs 5 (3)typedef struct _FacebookService_getName_result_isset _FacebookService_getName_result_isset; 7 (4)class FacebookService_getName_result 9 (5)typedef struct _FacebookService_getName_presult_isset _FacebookService_getName_presult_isset;11 (6)class FacebookService_getName_presult上面这六个类定义就

9、是为服务中的getName函数服务的,相应的每一个函数都会有这种类似的定义和实现。接下来就会定义三个具体实现IDL定义的功能的类,一个客户端的类,它继承定义的服务抽象类,每一个具体的函数实现都是同样的方式和思路,同样我结合getName函数的实现来看看这个过程,其他函数都是这样实现的,代码如下:1 send_getName();3 recv_getName(_return);由上面代码可以看出首先调用函数发送函数名称及相关信息到远程,然后接受函数调用的返回值,发送函数send_getName()的代码如下: 1 int32_t cseqid = 0; 3 oprot_-writeMessage

10、Begin(getName, :apache:thrift:T_CALL, cseqid);/写一个函数调用消息RPC 5 FacebookService_getName_pargs args; 7 args.write(oprot_);/写入参数 9 oprot_-writeMessageEnd();11 oprot_-getTransport()-writeEnd();13 oprot_-flush();/保证这次写入过程立即生效上面代码就完成了函数名称以及参数的传输,调用的是TProtocol相关的类的函数实现,具体的实现内容和方式会在TProtocol部分介绍。下面接着看一下接收返回值

11、的函数recv_getName的代码: 1 int32_t rseqid = 0;/接收的消息序列号 3 std:string fname;/函数名称 5 :TMessageType mtype;/消息的类型(调用(T_CALL)、异常(T_EXCEPTION)等) 7 iprot_-readMessageBegin(fname, mtype, rseqid);/从返回消息读取函数名称、消息类型 9 if (mtype = :T_EXCEPTION) /处理异常消息11 :TApplicationException x;13 x.read(iprot_);15 iprot_-readMessa

12、geEnd();17 iprot_-readEnd();19 throw x;23 if (mtype != :T_REPLY) /处理返回消息25 iprot_-skip(:T_STRUCT);27 iprot_-29 iprot_-31 33 if (pare() != 0) /看是否是我们需要的函数名,不是就跳过消息读取35 iprot_-37 iprot_-39 iprot_-41 43 FacebookService_getName_presult result;45 result.success = &_return;47 result.read(iprot_);/读取函数返回值4

13、9 iprot_-51 iprot_-52 53 if (result._isset.success) /成功就返回结果(已经在_return里面),否则抛出异常54 55 return;56 57 58 59 throw :TApplicationException(:TApplicationException:MISSING_RESULT, getName failed: unknown result);上面代码就是处理远程调用的返回结果,代码里面有注释。一个服务函数的实现大概流程已经展现在我们面前了,处理的过程也已经清晰。这个只是用于客户端的处理流程,必须通过有效的机制来通知服务器端调用

14、相应的函数(这就是RPC)在服务器端完成相应功能并将结果返回。这种机制就是通过我们这部分介绍的TProcessor类实现,这就是上面提到三个类中的第二个类,在这个实例中是FacebookServiceProcessor类,它从TProcessor类继承,重点实现两个函数process和process_fn,其中process会调用process_fn函数来处理客户端具体调用的那个服务函数,process函数定义如下: 1 bool FacebookServiceProcessor:process(boost: : piprot, 3 boost: poprot, void* callConte

15、xt) TProtocol* iprot = piprot.get(); 7 :TProtocol* oprot = poprot.get(); 9 std:13 int32_t seqid;15 iprot-readMessageBegin(fname, mtype, seqid);/读取得到函数名称、消息类型和函数序列号17 /处理不是函数调用消息的情况19 if (mtype !T_CALL & mtype !T_ONEWAY) 21 iprot-23 iprot-25 iprot-27 :TApplicationException x(:INVALID_MESSAGE_TYPE);29

16、 /写入(返回)一个异常信息给调用客户端,客户端会根据返回结果处理异常31 oprot-writeMessageBegin(fname, :T_EXCEPTION, seqid);33 x.write(oprot);35 oprot-37 oprot-39 oprot-41 return true;43 45 return process_fn(iprot, oprot, fname, seqid, callContext);/调用实际的函数处理47 上面代码有比较详细的注释,还需要说明一点的就是如果传递的不是函数调用的消息类型就会返回给客户端一个异常的消息,客户端的接收返回值的函数就会根据收

17、到的异常消息做相应处理,上面getName函数的接收返回值函数就是抛出一个服务器端给的异常信息。下面继续看最终服务器端调用相应映射函数的处理,这个是通过process_fn函数实现:具体定义如下:process_fn(:TProtocol* iprot, 3 :TProtocol* oprot, std: fname, int32_t seqid, void* callContext) 5 /定义个map的迭代器,用于接收在函数映射查找到的映射函数 7 std:string, void (FacebookServiceProcessor:*)(int32_t, :TProtocol*, 9 :

18、TProtocol*, void*)iterator pfn;11 pfn = processMap_.find(fname);/根据函数名称查找对应的映射处理函数13 if (pfn = processMap_.end() /如果没有找到,做下面的处理17 iprot-19 iprot-21 /抛出一个不知道的方法的异常23 :UNKNOWN_METHOD, 25 Invalid method name: +fname+27 /写入到调用客户端29 oprot-31 x.write(oprot);33 oprot-39 return true;43 (this-*(pfn-second)(s

19、eqid, iprot, oprot, callContext);/调用具体的函数(RPC过程完成)45 return true;上面这个函数最终完成了RPC的过程,那个函数与映射函数的对应关系的map结构是在构造函数中初始化的,所以可以找到,例如我们举例的getName函数是下面这样初始化的:1 processMap_ = &FacebookServiceProcessor:process_getName;和getName函数一样,对于IDL定义的每一个函数在FacebookServiceProcessor类中都有一个映射的处理函数,为了展示一个完整的处理过程我们在看看getName函数的映

20、射处理函数process_getName,它的定义如下: 1 void FacebookServiceProcessor:process_getName(int32_t seqid,TProtocol* iprot, :TProtocol* oprot, void* callContext) 5 7 void* ctx = NULL; 9 if (eventHandler_.get() != NULL) 11 /得到上下文调用环境13 ctx = eventHandler_-getContext(FacebookService.getName, callContext);15 17 /定义并初始化一个用于释放资源的帮助类对象19 :TProcessorContextFreer freer(eventHandler_.get(), ctx, 21 if (eventHandler_.get() !23 eventHandler_-preRe

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2