0%

Thrift 学习


####类型相关

  • 基本类型

    1
    2
    3
    4
    5
    6
    7
    bool:布尔值 (true or false), one byte
    byte:有符号字节
    i16:16位有符号整型
    i32:32位有符号整型
    i64:64位有符号整型
    double:64位浮点型
    string:未知编码或者二进制的字符串
  • 结构体和异常类型

    • Thrift 结构体 (struct) 在概念上类似于 C 语言结构体类型,在 java 中 Thrift 结构体将会被转换成面向对象语言的类。
1
2
3
4
5
6
struct UserDemo {
  1: i32 id;
  2: string name;
  3: i32 age = 25;
  4: string phone;
}
1
2
3
4
5
6
7
struct 不能继承,但是可以嵌套,不能嵌套自己
其成员都是有明确类型
成员是被正整数编号过的,其中的编号使不能重复的,这个是为了在传输过程中编码使用
成员分割符可以是逗号(,)或是分号(;),而且可以混用,但是为了清晰期间,建议在定义中只使用一种,比如java学习者可以就使用逗号(;)
字段会有optional和required之分
每个字段可以设置默认值
同一文件可以定义多个struct,也可以定义在不同的文件,进行include引入
  • 容器类型
    1
    2
    3
    list<t>:元素类型为t的有序表,容许元素重复。对应java的ArrayList,C# 中的 List<T>
    set<t>:元素类型为t的无序表,不容许元素重复。对应java和C#中的的HashSet
    map<t,t>:键类型为t,值类型为t的kv对,键不容许重复。对对应Java的HashMap,C#中的Dictionary
  • 服务类型
    1
    2
    3
    4
    service QuerySrv{
      UserDemo qryUser(1:string name, 2:i32 age);
      string queryPhone(1:i32 id);
    }
  • 命名空间
    • Thrift 中的命名空间类似于 java 中的 package,C#中的namespace,它们提供了一种组织(隔离)代码的简便方式。名字空间也可以用于解决类型定义中的名字冲突。

###传输

  • 传输协议
    • 上总体可划分为文本 (text) 和二进制 (binary) 传输协议两大类
1
2
3
4
TBinaryProtocol:是Thrift的默认协议,使用二进制编码格式进行数据传输,基本上直接发送原始数据   
TCompactProtocol:压缩的、密集的数据传输协议,基于Variable-length quantity的zigzag 编码格式
TJSONProtocol:以JSON (JavaScript Object Notation)数据编码协议进行数据传输
TDebugProtocol:常常用以编码人员测试,以文本的形式展现方便阅读
  • 传输方式
    • TSocket:阻塞型 socket,用于客户端,采用系统函数 read 和 write 进行读写数据。
    • TServerSocket:非阻塞型 socket,用于服务器端,accecpt 到的 socket 类型都是 TSocket(即阻塞型 socket)。
    • TBufferedTransport 和 TFramedTransport 都是有缓存的,均继承TBufferBase,调用下一层 TTransport 类进行读写操作吗,结构极为相似。其中 TFramedTransport 以帧为传输单位,帧结构为:4个字节(int32_t)+传输字节串,头4个字节是存储后面字节串的长度,该字节串才是正确需要传输的数据,因此 TFramedTransport 每传一帧要比 TBufferedTransport 和 TSocket 多传4个字节。
    • TMemoryBuffer 继承 TBufferBase,用于程序内部通信用,不涉及任何网络I/O,可用于三种模式:(1)OBSERVE模式,不可写数据到缓存;(2)TAKE_OWNERSHIP模式,需负责释放缓存;(3)COPY模式,拷贝外面的内存块到TMemoryBuffer。
    • TFileTransport 直接继承 TTransport,用于写数据到文件。对事件的形式写数
      据,主线程负责将事件入列,写线程将事件入列,并将事件里的数据写入磁盘。这里面用到了两个队列,类型为 TFileTransportBuffer,一个用于主线程写事件,另一个用于写线程读事件,这就避免了线程竞争。在读完队列事件后,就会进行队列交换,由于由两个指针指向这两个队列,交换只要交换指针即可。它还支持以 chunk(块)的形式写数据到文件。
    • TFDTransport 是非常简单地写数据到文件和从文件读数据,它的 write 和
      read 函数都是直接调用系统函数 write 和 read 进行写和读文件。
    • TSimpleFileTransport 直接继承 TFDTransport,没有添加任何成员函数和成员变量,不同的是构造函数的参数和在 TSimpleFileTransport 构造函数里对父类进行了初始化(打开指定文件并将fd传给父类和设置父类的close_policy为CLOSE_ON_DESTROY)。
    • TZlibTransport 跟 TBufferedTransport 和 TFramedTransport一样,调用下一层 TTransport 类进行读写操作。它采用<zlib.h>提供的 zlib 压缩和解压缩库函数来进行压解缩,写时先压缩再调用底层 TTransport 类发送数据,读时先调用 TTransport 类接收数据再进行解压,最后供上层处理。
    • TSSLSocket 继承 TSocket,阻塞型 socket,用于客户端。采用 openssl 的接口进行读写数据。checkHandshake()函数调用 SSL_set_fd 将 fd 和 ssl 绑定在一起,之后就可以通过 ssl 的 SSL_read和SSL_write 接口进行读写网络数据。
    • TSSLServerSocket 继承 TServerSocket,非阻塞型 socket, 用于服务器端。accecpt 到的 socket 类型都是 TSSLSocket 类型。
    • THttpClient 和 THttpServer 是基于 Http1.1 协议的继承 Transport 类型,均继承 THttpTransport,其中 THttpClient 用于客户端,THttpServer 用于服务器端。两者都调用下一层 TTransport 类进行读写操作,均用到TMemoryBuffer 作为读写缓存,只有调用 flush() 函数才会将真正调用网络 I/O 接口发送数据。
    • TTransport 是所有 Transport 类的父类,为上层提供了统一的接口而且通过 TTransport 即可访问各个子类不同实现,类似多态。