文档章节

Thrift RPC实战(三) Thrift序列化机制

lemonLove
 lemonLove
发布于 06/20 20:21
字数 1032
阅读 44
收藏 0

1.Thrift基础架构    

Thrift是一个客户端和服务端的架构体系,数据通过socket传输;

具有自己内部定义的传输协议规范(TProtocol)和传输数据标准(TTransports);

通过IDL脚本对传输数据的数据结构(struct) 和传输数据的业务逻辑(service)根据不同的运行环境快速的构建相应的代码;

通过自己内部的序列化机制对传输的数据进行简化和压缩提高高并发、 大型系统中数据交互的性能。

  (1)  Thrift 数据类型

基本类型:
  bool: 布尔值
  byte: 8位有符号整数
  i16: 16位有符号整数
  i32: 32位有符号整数
  i64: 64位有符号整数
  double: 64位浮点数
  string: UTF-8编码的字符串
  binary: 二进制串
结构体类型:
  struct: 定义的结构体对象
容器类型:
  list: 有序元素列表
  set: 无序无重复元素集合
  map: 有序的key/value集合
异常类型:
  exception: 异常类型
服务类型:
  service: 具体对应服务的类

  (2)  协议

Thrift可以让你选择客户端与服务端之间传输通信协议的类别,在传输协议上总体上划分为文本(text)和二进制(binary)传输协议, 为节约带宽,提供传输效率,一般情况下使用二进制类型的传输协议为多数,但有时会还是会使用基于文本类型的协议,这需要根据项目/产品中的实际需求:
    1、TBinaryProtocol – 二进制编码格式进行数据传输。
    2、TCompactProtocol – 这种协议非常有效的,使用Variable-Length Quantity (VLQ) 编码对数据进行压缩。
    3、TJSONProtocol – 使用JSON的数据编码协议进行数据传输。
    4、TSimpleJSONProtocol – 这种节约只提供JSON只写的协议,适用于通过脚本语言解析
    5、TDebugProtocol – 在开发的过程中帮助开发人员调试用的,以文本的形式展现方便阅读。

(3)传输层

    1、TSocket- 使用堵塞式I/O进行传输,也是最常见的模式。
    2、TFramedTransport- 使用非阻塞方式,按块的大小,进行传输,类似于Java中的NIO。
    3、TFileTransport- 顾名思义按照文件的方式进程传输,虽然这种方式不提供Java的实现,但是实现起来非常简单。
    4、TMemoryTransport- 使用内存I/O,就好比Java中的ByteArrayOutputStream实现。

    5、TZlibTransport- 使用执行zlib压缩,不提供Java的实现。

(3)服务服务模型

        https://my.oschina.net/u/3737136/blog/1833054

2.Thrift序列化机制

Thrift提供了可扩展序列化机制, 不但兼容性好而且压缩率高。

   thrift 数据格式描述

   thrift的向后兼容性(Version)借助属性标识(数字编号id + 属性类型type)来实现, 可以理解为在序列化后(属性数据存储由 field_name:field_value => id+type:field_value)

 我们定义IDL文件形如

namespace java stu.thrift;
 
struct User {
  1: required string name
  2: required string address
}

thrift的向后兼容性(Version)借助属性标识(数字编号id + 属性类型type)来实现, 可以理解为在序列化后(属性数据存储由 field_name:field_value => id+type:field_value), 这也解释了上述提到的场景的原因了.
 进行代码解读:

public void read(org.apache.thrift.protocol.TProtocol iprot, User struct) throws org.apache.thrift.TException {
  org.apache.thrift.protocol.TField schemeField;
     //读取结构开始标记
  iprot.readStructBegin();
  while (true)
  {
    // 读取Field属性开始标记
    schemeField = iprot.readFieldBegin();
    if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
      break;
    }
    switch (schemeField.id) {
      case 1: // name
        if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
          struct.name= iprot.readString();
          struct.setNameIsSet(true);
        } else { 
          org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        break;
      case 2: // address
        if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
          struct.address= iprot.readString();
          struct.setAddressIsSet(true);
        } else { 
          org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        break;
      default:
        org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
    }
    iprot.readFieldEnd();
  }
  iprot.readStructEnd();

  // check for required fields of primitive type, which can't be checked in the validate method
  struct.validate();
}

最终会被细化为readStructBegin, readFieldBegin, read<type>(readString, readI32, readI64), readFieldEnd, readStructEnd的有组织有序调用.

Thrift官方文档, 也提到对新增的字段属性, 采用id递增的方式标识并以optional修饰来添加.

 

© 著作权归作者所有

共有 人打赏支持
lemonLove
粉丝 29
博文 55
码字总数 61347
作品 0
深圳
后端工程师
thrift使用介绍

原文出处:http://gemantic.iteye.com/blog/1199214 一、About thrift 二、什么是thrift,怎么工作? 三、Thrift IDL 四、Thrift Demo 五、Thrift 协议栈 以及各层的使用(java 为例) 六、与...

ponpon_
2014/07/07
0
0
架构设计:系统间通信(12)——RPC实例Apache Thrift 中篇

(接上文《架构设计:系统间通信(11)——RPC实例Apache Thrift 上篇》) 3、Aapche Thrift详解 在《架构设计:系统间通信(10)——RPC的基本概念》一文中,我专门介绍了一款RPC规范的具体...

引鸩怼孑
2016/01/29
38
0
Thrift之Protocol源码分析

 之前写过两篇关于 Thrift 的相关文章。 Thrift源码剖析 Thrift异步IO服务器源码分析 也算是对Thrift比较熟悉,不过对 Thrift 里面的 Protocol 部分还是黑盒使用。 虽然大概能猜到具体实...

nothingfinal
2016/04/23
0
0
thrift中使用list数据类型传输大数据瓶颈及解决方案

董的博客中thrift相关基础的介绍:http://dongxicheng.org/search-engine/thrift-rpc/ thrift碰到大list时瓶颈的原因: 因为thrift协议中server和client的交互使用的是序列化的数据。当你使用...

liujiest
2016/09/01
197
0
CRUD并不易-- --谈微服务中的序列化场景

在上一篇文章中说到了验参,现在接着说另一个微服务中的工程性问题,序列化。 作为编写业务的程序员,常被戏称为CRUD程序写,会增删改查,给个if else给个for就能混碗饭吃。此话倒不假。 在面...

古二白
08/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

你为什么在Redis里读到了本应过期的数据

一个事故的故事 晚上睡的正香突然被电话吵醒,对面是开发焦急的声音:我们的程序在访问redis的时候读到了本应过期的key导致整个业务逻辑出了问题,需要马上解决。 看到这里你可能会想:这是不...

IT--小哥
今天
2
0
祝大家节日快乐,阖家幸福! centos GnuTLS 漏洞

yum update -y gnutls 修复了GnuTLS 漏洞。更新到最新 gnutls.x86_64 0:2.12.23-22.el6 版本

yizhichao
昨天
5
0
Scrapy 1.5.0之选择器

构造选择器 Scrapy选择器是通过文本(Text)或 TextResponse 对象构造的 Selector 类的实例。 它根据输入类型自动选择最佳的解析规则(XML vs HTML): >>> from scrapy.selector import Sele...

Eappo_Geng
昨天
4
0
Windows下Git多账号配置,同一电脑多个ssh-key的管理

Windows下Git多账号配置,同一电脑多个ssh-key的管理   这一篇文章是对上一篇文章《Git-TortoiseGit完整配置流程》的拓展,所以需要对上一篇文章有所了解,当然直接往下看也可以,其中也有...

morpheusWB
昨天
5
0
中秋快乐!!!

HiBlock
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部