资讯专栏INFORMATION COLUMN

thrift调用流程分析

nidaye / 1138人阅读

摘要:由于工作需要使用,并且需要根据需求修改源码,因此必须熟悉执行的流程。目前支持的模型包括使用阻塞的单线程服务器,主要用于调试。

由于工作需要使用thrift,并且需要根据需求修改thrift源码,因此必须熟悉thrift执行的流程。以下是根据thrift源码阅读而得出流程分析。

thrift协议栈概述

thrift是一个rpc框架,开发者可以通过thrift自带的接口定义语言(IDL)来自动生成客户端和服务端的rpc代码。
thrift协议栈如下图所示:

在client和server的最顶层都是用户自定义的处理逻辑,也就是说用户只需要编写用户逻辑,就可以完成整套的rpc调用流程。用户逻辑的下一层是thrift自动生成的代码,这些代码主要用于结构化数据的解析、发送和接收,同时服务端的自动生成代码中还包含了rpc请求的转发(client的A调用转发到server A函数进行处理)。

从上面可以看出thrift的模块是分层设计的,在每一个层次可以根据业务的实际需要选择合适的实现方式。

thrift主要分为以下几种层次模块:

底层io模块,负责实际的数据传输,包括socket、文件或压缩数据流等。

transport层负责以字节流方式发送和接收消息,是底层io模块在thrift框架中的实现,每一个底层io模块都会有一个对于TTransport来负责thrift的字节流(byte stream)数据在该io模块上的传输。例如,TSocket对应socket传输,TFileTransport对应文件传输。

TProtocol主要负责结构化数据组装成消息,或者从消息结构中读出结构化数据。TProtocol将一个有类型的数据转化为特定类型的数据。如int32会被TBinaryProtocol编码为一个4字节数据,或TBinaryProtocol从TTransport中取出4个字节数据解码为int32。

TServer负责接收client请求,并将请求转发到processor进行处理。TServer主要任务是高效地接受client的请求,特别是高并发请求的情况下快速完成请求。

processor负责对client的请求进行响应,包括rpc请求转发,调用参数解析和用户逻辑调用,返回值写回等处理步骤。processor是服务端从thrift框架转入用户逻辑的关键流程。processor同时也负责向消息结构中写入数据或读出数据。

TServer

thrift核心库提供了一个TServer抽象类。

TServer在thrift框架中的主要任务是接收client请求,并转发到某个processor上进行请求处理。针对不同的访问规模,thrift提供了不同TServer模型。thrift目前支持的server模型包括:

TSimpleServer:使用阻塞io的单线程服务器,主要用于调试。

TThreadedServer:使用阻塞io的多线程服务器,每一个请求都在一个线程中处理,并发访问情况下会有很多线程同时运行。

TThreadPoolServer:使用阻塞io的多线程服务器,使用线程池管理处理线程。

TNonBlockingServer:使用非阻塞io的多线程服务器,使用少量线程既可以完成大并发量的请求响应,必须使用TFramedTransport。

TServer对象通常如下工作:

使用TServerTransport获得一个TTransport。

使用TTransportFactory,可选地将原始传输转换为一个合适的应用传输。

调用TProtocolFactory,为TTransport创建一个输入和输出。

调用TProcessor对象的process方法。

TTransport

TTransport是与底层数据传输紧密相关的传输层。每一种支持的底层传输方式都存在一个与之对应的TTransport。在这一层,数据是按字节流处理的,即传输层看到的是一个又一个的字节,并把这些字节按顺序发送和接收。TTransport并不了解它所传输的数据是什么类型,实际上传输层也不关心数据是什么类型,只需要按照字节方式对数据进行发送和接收即可。数据类型的解析在TProtocol这一层完成。

TTransport具体的有以下几个类:

TSocket:使用阻塞的TCP socket进行数据传输,也是最常见的模式。

THttpTransport:采用http传输协议进行数据传输。

TFileTransport:文件(日志)传输类,允许client将文件传给server,允许server将收到的数据写到文件中。

TZlibTransport:与其他transport配合使用,压缩后对数据进行传输,或者将收到的数据解压。

TProtocol

TProtocol的主要任务是把TTransport中的字节流转换为数据流。在TProtocol这一层就会出现具有数据类型的数据,如整型、浮点数、字符串和结构体等。TProtocol中数据虽然有了数据类型,但TProtocol只会按照指定类型将数据读出和写入,而对于数据的真正用途,需要在thrift自动生成的server和client中处理。

thrift可以让用户选择客户端与服务端之间传输通信协议的类别,在传输协议上总体划分为文本和二进制传输协议,以节约带宽,提高传输效率,一般情况下使用二进制类型的传输协议为大多数。常用协议有以下几种:

TBinaryProtocl:二进制编码格式

TCompactProtocol:高效率的、密集的二进制编码格式

TJSONProtocol:使用JSON的数据编码协议进行数据传输

TSimpleJSONProtocol:提供JSON只写协议,生成的文件很容易通过脚本语言解析

TDebugProtocol:简单易懂的文本格式,以便于debug

TProcessor

TProcessor主要对TServer中一次请求的inputProtocol和outputProtocol进行操作,也就是从inputProtocol中读出client的请求数据,向outputProtocol写入用户逻辑的返回值。TProcessorprocess是一个非常关键的处理函数,因为client所有的rpc调用都会经过该函数处理并转发。

TProcessor对一次rpc调用的处理流程可以概括为:

TServer接收到rpc请求之后,调用TProcessorprocess进行处理。

TProcessorprocess首先调用TTransport.readMessageBegin接口,读出rpc调用的名称和rpc调用类型。如果rpc调用类型是rpc call,则调用TProcessor.process_fn继续处理,对于未知的rpc调用类型,则抛出异常。

TProcessor.process_fn根据rpc调用名称,到自己的processMap中查找对应的rpc处理函数。如果存在对应的rpc处理函数,则调用该处理函数继续进行请求响应。不存在则抛出异常。

而rpc处理函数是rpc请求的最终步骤,主要有以下三个过程:

调用rpc请求参数的解析类,从TProtocol中读入数据完成参数解析。不管rpc调用的参数有多少个,thrift都会将参数放到一个结构体中。thrift会检查读出参数的字段id和字段类型是否与要求的参数匹配。对于不符合要求的参数都会跳过。这样,rpc接口发生变化之后,旧的处理函数在不做修改的情况下,可以通过跳过不认识的参数,来继续提供服务。

参数解析完后,调用用户逻辑,完成真正的请求响应。

用户逻辑的返回值使用返回值打包类进行打包,写入TProtocol。

ThriftClient

ThriftClient跟TProcessor一样主要操作inputProtocol和outputProtocol,不同的是thriftClient将rpc调用分为send和receive两个步骤:

send步骤,将用户的调用参数作为一个整体的struct写入TProtocol,并发送到TServer。

send结束后,thriftClient便立即进入receive状态等待TServer的响应。对于TServer的响应,使用返回值解析类进行返回值解析,完成rpc调用。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/35925.html

相关文章

  • 后端必备——数据通信知识(RPC、消息队列)一站式总结

    摘要:具体可以参考消息队列之具体可以参考实战之快速入门十分钟入门阿里中间件团队博客是一个分布式的可分区的可复制的基于发布订阅的消息系统主要用于大数据领域当然在分布式系统中也有应用。目前市面上流行的消息队列就是阿里借鉴的原理用开发而得。 我自己总结的Java学习的系统知识点以及面试问题,目前已经开源,会一直完善下去,欢迎建议和指导欢迎Star: https://github.com/Snail...

    Kahn 评论0 收藏0
  • Thrift 简易入门与实战

    摘要:简介是一个软件框架用来进行可扩展且跨语言的服务的开发它结合了功能强大的软件堆栈和代码生成引擎以构建在这些编程语言间无缝结合的高效的服务官网地址安装的安装比较简单在下可以直接使用快速安装或可以通过官网下载这里就不再多说了当下载安装完毕后我们就 简介 thrift是一个软件框架, 用来进行可扩展且跨语言的服务的开发. 它结合了功能强大的软件堆栈和代码生成引擎, 以构建在 C++, Java...

    iliyaku 评论0 收藏0
  • Java字节码修改神器HiBeaver:黑掉你的SDK

    摘要:下面我们正式开始尝试小米推送,首先,找出其业务逻辑中的一个节点。因为小米推送是商业产品,这里不便于探索太多内容,但是通过这个插件可以比较方便的进行类似的研究。 前言 有时候我们在Java开发过程中可能有这样的需求:需要研究或者修改工程依赖的Jar包中的一些逻辑,查看代码运行中Jar包代码内部的取值情况(比如了解SDK与其服务器通信的请求报文加密前的情况)。 这个需求类似于Hook。 但...

    Lavender 评论0 收藏0

发表评论

0条评论

nidaye

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<