• Thrift 代码分析


    Thrift的基本结束

    Thrift是一个跨语言的服务部署框架,最初由Facebook于2007年开发,2008年进入Apache开源项目。Thrift通过IDL(Interface Definition Language,接口定义语言)来定义RPC(Remote Procedure Call,远程过程调用)的接口和数据类型,然后通过thrift编译器生成不同语言的代码(目前支持C++,Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk和OCaml),并由生成的代码负责RPC协议层和传输层的实现。

    Thrift代码分析

    Thrift代码分析,可以借鉴和学习的方面:

    1、代码分层设计,Thrift分传输层、协议层、处理层、服务层四个层设计,上层只依赖下层,方便扩展和维护。

    2、基于接口编程和多用抽象工厂设计,每层之间都有一个核心的接口,各个实体初始化基本是使用工厂设计模式,降低耦合。

    3、基于BIO和NIO,满足不同情景,便于性能调优。

    层次如下图:

    clip_image001

    各层的调用顺序如下图:

    image

    各层的类设计如下

    传输层

    image

    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校验

    协议层

    clip_image001[4]

    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层

    image

    TServer :基础抽象类,实际上类似一个容器,持有TProcessor、TTransport、TProtocol的工厂对象,AbstractServerArgs作为参数抽象类,提供一个serve()方法,用于启动服务,stop()方法停止服务。

    TSimpleServer :单线程阻塞式服务,只用于做测试的简单服务类。

    TNonblockingServer:支持非阻塞单线程服务模型,基于NIO的Select实现。

    THsHaServer:继承TNonblockingServer。单线程处理I/O,线程池请求的处理。

    TThreadedSelectorServer: 继承AbstractNonblockingServer。维持两个线程池,一个线程池处理I/O,另一个线程池处理请求。  以下代码时默认的线程池设置:

      1 Public class TThreadedSelectorServer extends AbstractNonblockingServer{
      2  3 Public static class Args extends AbstractNonblockingServerArgs<TThreadedSelectorServer.Args>{
      4 Public int selectorThreads = 2;
      5 Private int workerThreads = 5;
      6 Private int stopTimeoutVal = 60;

    TThreadPoolServer:专门的线程接受请求并交给线程池处理,完成后线程池连接释放。请求处理线程和I/O线程为同一线程。阻塞式线程池模型。

    Processer层

    image

    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的工厂类

    (The End)

  • 相关阅读:
    Eclipse自动换行插件
    JAVA中super与this的区别
    外网访问PG数据库,如何赋予IP访问权限
    PostgreSQL环境变量与psql命令的替代作用
    \l 的使用
    一次生成任意多行数据的语句
    equals与==的区别
    PostgreSQL 名词理解EXPLAIN VERBOSE
    PG坑爹的数组定义
    【收藏】常用的ftp命令
  • 原文地址:https://www.cnblogs.com/tyol/p/10562394.html
Copyright © 2020-2023  润新知