RPC框架之Thrift分析

本文深入解析了Facebook开发的跨语言RPC框架Thrift。包括其架构组成、各组件功能及其实现原理,如传输层、协议层和服务层的设计,并探讨了不同服务模型的特点。

一、简介

1、Thrift是Facebook开发的跨语言的RPC服务框架。随后贡献给Apache开源组织。成为RPC服务的主流框架。

2、特点:
 优点:
      跨语言,支持java、c/c++、python等多种编程语言
      IDL定义接口函数和数据类型
      支持二进制传输,效率高
      支持多种工作模型,单线程模型、线程池模型、非阻塞模型
 
 缺点:
      文档不多

      各版本不兼容,升级不方便

二、分析



Thrift分为服务端(server)和客户端(Client)两个对应的部分。代码分层设计,分为Transport(传输层)、Protocol(协议层)、Processor(处理层)和Server(服务层)。

1、主要的处理流程:

各部分类图:

传输层

TTransport:客户端传输层抽象基础类,主要方法:read、write、flush、open、close。read、write方法为核心
TSocket TNonBlockingSocket:分别是基于BIO和NIO客户端传输类。 TSocket持有Socket,设置输入输出流使用1K的BufferedStream,
TNonBlockingSocket持有SocketChannel,read和write方法里的byte会每次被wrap成一个ByteBuffer。
TServerSocket TNonBlockingServerSocket:分别是基于BIO和NIO服务端传输类。TServerSocket持有ServerSocket,TNonBlockingServerSocket持有ServerSocketChannel。
TFramedTransport与TFastFramedTransport:将数据封装Frame(帧)实现的, TFastFramedTransport效率内存使用率高,使用了自动扩展长度的buffer
TZlibTransport:读取时按1K为单位将数据读出并调用JDK的zip函数进行解压再放到Buffer,写入时,在flush时先zip再写入。
TSaslClientTransport与TSaslServerTransport:提供SSL校验



协议层:

1)IDL 定义支持类型:
   基本类型: i16,i32,i64, double, boolean,byte,byte[], String。
   容器类型: List,Set,Map,TList/TSet/TMap类包含其元素的类型与元素的总个数。
   Struct类型:即面向对象的Class,继承于TBase。TStruct类有Name属性,还含有一系列的Field。TField类有自己的Name,类型,顺序id属性。
   Exception类型:Struct,继承于TException这个checked exception。
   Enum类型:传输时是个i32。
   Message类型:封装往返的RPC消息。TMessage类包含Name,类型(请求,返回,异常,ONEWAY)与seqId属性。

2) 类分析:
TProtocol:基础抽象类,拥有对IDL定义支持类型read和write方法,对于结构类型先readxxBegin()(或writexxBegin()),结束时调用readxxEnd() (或readxxEnd())方法。
TBinaryProtocol:二进制流传输协议类,把各类型转换成byte数组,交给TTransport传输。
TCompactProtocol:压缩方法二进制协议类,将Integer按照ZigZag
TTupleProtocol:继承TCompactProtocol,Struct使用时更省空间
TJSONProtocol:Json格式协议类,将数据封装成Json格式,再转为byte数组交给传输层。
TSimpleJSONProtocol:Json格式协议类,但只支持写的功能。
TProtocolFactory:TProtocol的工厂基础类,每个TProtocol实现类均有一个工厂实现。


Server层



TServer 基础抽象类,实际上类似一个容器,持有TProcessor、TTransport、TProtocol的工厂对象,AbstractServerArgs作为参数抽象类,提供一个serve()方法,用于启动服务,stop()方法停止服务。
TSimpleServer :单线程阻塞式服务,只用于做测试的简单服务类。
TNonblockingServer:支持非阻塞单线程服务模型,基于NIO的Select实现。
THsHaServer:继承TNonblockingServer。单线程处理I/O,线程池请求的处理。
TThreadedSelectorServer: 继承AbstractNonblockingServer。维持两个线程池,一个线程池处理I/O,另一个线程池处理请求。  TThreadPoolServer:专门的线程接受请求并交给线程池处理,完成后线程池连接释放。请求处理线程和I/O线程为同一线程。阻塞式线程池模型。
以上五种模型参见:
https://github.com/m1ch1/mapkeeper/wiki/Thrift-Java-Servers-Compared
http://blog.youkuaiyun.com/houjixin/article/details/42779915



Processer层



TProcessor:基础接口,抽象方法process(TProtocol in, TProtocol out)
TBaseProcessor 基础抽象类,持有processMap对象,key为方法名标示,value为方法(ProcessFunction的实例),实现TProcessor的方法process,in.readMessageBegin()拿到传过来的方法名,如果存在则准备交给具体业务类执行,否则抛出无效方法的异常。
Processor:IDL生成,实现TProcessor接口并继承TBaseProcessor类。
TAsyncProcessor:异步处理接口,抽象方法process(final AsyncFrameBuffer fb) TBaseAsyncProcessor:异步处理抽象类,持有processMap对象,key为方法名标示,value为方法(AsyncProcessFunction的实例),实现TAsyncProcessor的方法process(final AsyncFrameBuffer fb),AsyncProcessFunction的getResultHandler方法拿到一个AsyncMethodCallback,带执行start方法后通过sendResponse方法返回。 AsyncProcessor 由IDL生成,实现TAsyncProcessor接口并继承TAsyncProcessor类。
TProcessorFactory: 构建 TProcessor的工厂类


总结


Thrift代码分析,可以借鉴和学习的方面:
1、代码分层设计,Thrift分传输层、协议层、处理层、服务层四个层设计,上层只依赖下层,方便扩展和维护。 2、基于接口编程和多用抽象工厂设计,每层之间都有一个核心的接口,各个实体初始化基本是使用工厂设计模式,降低耦合。
3、基于BIO和NIO,满足不同情景,便于性能调优。




转载于:https://my.oschina.net/caiz/blog/667352

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值