thrift介绍及应用(一)—介绍

原文:http://blog.csdn.net/guxch/article/details/12157151

------------------------------------------------------------------------------------

一、概述

        Thrift是Apache下的一个子项目,最早是Facebook的项目,后来Facebook提供给Apache作为开源项目,在官网上,Thrift被描述为“Scalable Cross-Language Services Implementation”,说的通俗一些,Thrift具有以下特征:
  1. 它有自己的跨机器的通信框架,并提供一套库。
  2. 它是一个代码生成器,按照它的规则,可以生成多种编程语言的通讯过程代码。
        一般情况下的跨机器的通信框架都是跨软件平台的(Linux,windows), 而Thrift最特别之处在于它是跨语言的:例如,你可以用几乎所有流行语言(C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript等等)来实现通讯过程,这样做的好处就是你不用为编程语言发愁,如果服务器端与客户端都需要编写,选择你最拿手或项目规定的语言,就可以生成一个通讯框架;如果编写一个服务器端程序,定义好通讯规则(在Thrift中是.thrift文件)后,你所采用的服务器端实现语言不会影响到客户端,以后使用的人可以采用其他编程语言来实现客户端。真是件美好的事情!
        与Thrift相类似的开源项目是Google的Protocol Buffer(Protobuf),Protobuf目前提供了 C++、Java、Python 三种语言的 API,比Thrift简单一些,应用也不如Thrift广泛,有评论说Protobuf写复杂的应用比较困难。
        目前thrift的版本是0.9.1,以下的讨论均以该版为基准,代码语言以C++为基准。

二、Thrift应用场景

        Thrift其实应分成三个部分,一个叫做Thrift代码生成器,一个叫做Thrift应用框架(库),最后一个是它生成的代码。Thrift应用的基本流程如下图所示。

从上图,要生成一个Thrift应用,需用以下文件:

  1. 一个.thrift文件:该文件是通信接口的定义,最主要的是信息流的格式。
  2. 编程语言:这个无需解释。
  3. Thrift代码生成器(Thrift compiler,翻译成代码生成器似乎更合适):这个东西是安装thrift过程中生成的,它可以产生若干符合你约定通信格式的代码。
  4. Thrift应用框架库:这个东西也是在安装过程中产生的。
  5. 其他第三方支撑库:对C++来说,最主要是boost.thread、libevent,log4cxx等,按照运行的模式,生成的代码中可能需用调用这些库。

三、Linux下安装

        Thrift的安装包括上面提到生成代码生成器和应用框架库,网页(http://thrift.apache.org/docs/install/)描述了安装依赖项,除了gcc及其编译工具本身外,编译Thrift最大的依赖就是boost。安装过程并不复杂,请参阅相关网上文章。

四、Windows下Thrift的使用

        将Windows环境单独拿出来讨论是因为以前的Thrift版本(0.8以前)是不支持Windows的,虽然有些人做了补丁,但看其文档,相当麻烦。0.8开始支持windows,目前官方文档的描述中还是需要Cygwin这样的东西。其实0.9.1已经能很好的支持windows了。

        Thrift compiler的编译:在\compiler\cpp下有一个compiler.sln的VS2010的解决方案,它有一个叫做compiler的VC项目。可惜的是,要编译compiler,必须flex和bison的支持,这个可以到http://sourceforge.net/projects/winflexbison/?source=dlp下载,在VC的项目属性中,修改“生成事件->预先生成事件”中的命令行为(注意win_flex和win_bison的路径):

[plain] view plaincopy
  1. win_flex -o "src\\thriftl.cc"src/thriftl.ll  
  2.   
  3. win_bison -y -o "src\thrifty.cc"--defines="src/thrifty.hh" src/thrifty.yy  
再将inttypes.h(网上下载)和thrifty.h(在上级目录)拷到src目录下,编译即可。上面的步骤也可手工完成,这样更保险些(可以参考compiler\cpp\README_Windows.txt,但其中有点小错误)。

        Thrift库的编译:在“\lib\cpp”目录,有一个叫thrift.sln的VS2010的解决方案文件,它包含两个VC项目:libthriftnb和libthrift,libthrift依赖于boost,libthriftnb依赖于boost和libevent,在正确设置好引用库后(先要编译生成boost和libevent),可以编译这两个工程,得到两个dll,即thrift的应用框架库,在thrift应用中,需要使用这个框架库。

五、Thrift基本概念与应用

这一部分很多文章已经涉及,本文只是从Thrift的White Paper角度加一些个人理解与注释。

1.Thrift有以下几个概念:

类型系统(typesystem)

Thrift定义了一套数据传输描述语言(有点类似IDL),它是“语言中性”的,这个就是它的类型系统。它分为五种类型(数据类型表达3种,预定义类/结构1种,接口表达1种):

基本类型(basictype),也就是bool、byte、i16、i32、i64、double、string,任何语言都有这些基本类型,比较有意思的是string,它即表达text,也表达binary bytes。另一个特点是整型没有unsigned,原因比较简单,因为有些语言不支持。

  • 结构类型(struct):就是C语言中的struct,将基本类型组合起来。
  • 容器类型(container):就是集合类型(list/set/map),其中的元素是任何Thrift可识别的基本、结构、容器类型。【不知道是否有不支持list/set/map的语言,那么Thrift如何处理呢?】
  • 异常类型(exception):从数据结构讲就是结构类型,可以认为是便于异常的处理而单独拿出来的、预定义的、有特殊意义的结构类型。
  • 服务定义类型(service):这个类型实际是用来定义接口的,Thrift代码生成器会根据这个定义,生成代码框架。

传输(transport)

也就是信息的传输渠道以及读写方式,例如,介质可以是socket、shared memory或file,Thrift规定了一些基本的操作(open/close/isOpen/read/write/flush,对server,再加上listen/accept)。特别的,针对Socket方式,有TScoket类,对file方式,有TFileTransport类,上面类比较底层,还有几个实用的类:TBufferedTransport,TFramedTransport,TMemoryBuffer等。

 

协议(protocol)

是对传输协议的封装,也就是传输采用二进制、XML或者text来表示信息,它的功能有两个:1.双向的消息队列;2.信息的编码和解码(也就是对上面类型的读/写)。关于流式格式,thrift数据类型是自我分割的,意思是说,thrift会自己在数据域的分割处插入标志,在解码的时候,即使没有数据域定义,thrift也能成功分割出各数据域。在若干篇文章中,都提到thrift的二进制流式编码有相当的效率(可以配合压缩),因此首选的协议应该是binary协议。

 

版本(versioning)

如果一个程序分开来开发,那版本问题就是绕不过去的问题。Thrift的版本是通过“field identifiers”来实现的,每个结构由其标识,结构中的每个域有其标识,这两个标识唯一决定了一个数据域。在解码的时候,数据域的标识被检查,如果不能识别,则该数据域被抛弃。Thrift也可以通过”Isset”机制来明确某些域的设置与否(发送端用来指明是否设置,接收端用来检测是否设置)。

四种情况:

  1. 添加了数据域, 旧客户端,新服务器端:客户端发送的数据中没有该域,服务器端能检测出来,可按缺省值处理。
  2. 删除了数据域, 旧客户端,新服务器端:客户端发送的数据中有该域,服务器端忽略该域。
  3. 添加了数据域, 新客户端,旧服务器端:客户端发送的数据中有该域,服务器端忽略该域。
  4. 删除了数据域, 新客户端,旧服务器端:客户端发送的数据中没有该域,服务器端可能不知道如何处理这种情况。

 处理器(processor)

就是如何将各部分协调起来,形成代码(或用户代码的框架)。它有两个重要的类:TProcessor和TServer。TProcessor用来实现RPC调用,TServer是所有Server类的基类,TServer类主要处理连接和线程,而不管诸如传输、编码等。用户代码主要关注的一是.thrift文件,二就是这个接口。Thrift为此实现了TSimpleServer(单线程), TThreadedServer(每连接一个线程)和 TThreadPoolServer(线程池)等类。

下图是thrift生成代码的基本结构(C++)。


图中,ServiceIf是根据接口文件(.thrift)生成的虚接口类,用户的具体实现在ServiceHandler中。各种调用方式在TServer中实现。【详细的描述见实例】

 

2.Thrift实现上的几个考虑

目标语言

虽然有多种选择,但最常用的(可能也是支持最好的)是C++, Java, and Python。


生成的结构体

数据域成员都是公有的,没有set,get之类的东西,虽然建议采用isset,但也可以不用,系统足够强健来处理类似“FieldNotSetException”之类的问题,因而也没有涉及该异常。Read和write方面也是公有的,这样用户可以在固有的RPC之外来使用它们。

RPC方法标识:实现RPC时,建立函数名与函数指针之间的映射,大致如下(不同的语言表达方式不同,C++,map):

std::map<std::string,函数指针> processMap_;

这样加快函数调用。


多线程

对C++实现,在开发过程中,thrift开发人员研究过boost,ACE中与thread,timer相关的东西,开发人员不想引入过多的第三方依赖,因此thrift中只有对boost::shared_ptr的引用是必须的,但为了跨平台或获得更多的功能,一般情况下,boost中thread,timer及其依赖库也是需要的。


ThreadManager和TimerManager

线程管理类用来管理线程池,定时器管理类可以定时触发Runnable的对象,开启一件事情(可以放到或不放到一个单独线程)。


NonblockingOperation

这个东西需要libevent的支持。


Compiler(代码生成器)

这个东西是用C++写的,依赖于lex/yacc。代码生成分两步:第一,检查包含的文件和类型定义文件,生成“解析树”(the parse tree);第二,将各类型放到解析树中,根据解析树生成代码。


TFileTransport

这个类(及其继承类)可以将request消息记入文件,为提高性能,它先缓存记录,并存入磁盘。记录文件是分块的(文件固定大小),采用padding,记录不能跨块。



(未完)


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/539275.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

matlab双目相机标定校正_基于双目视觉的无人机避障算法(一)

讲述在10月到12月所做的所有工作对于一个无人机自主避障来说&#xff0c;存在着以下流程&#xff1a;感知&#xff1a;障碍物检测、行人检测、目标检测SLAM&#xff1a;为无人机提供位置估计&#xff0c;构建稀疏环境地图路径规划&#xff1a;规划一条从当前位置到目标位置的移…

计算机无法播放,如果无法播放计算机mp4文件怎么办?

FireStar365接受1. 下载并安装最新版本的视频播放器(例如: Storm Video).2. 在硬盘中找到MP4视频文件.3. 右键单击该文件&#xff0c;然后选择打开方法“ Storm Video”.4. 可以双击打开页面.zxc942128835将mp4链接到计算机&#xff0c;打开磁盘&#xff0c;单击菜单栏上的工具…

thrift介绍及应用(二)—简单应用

原文&#xff1a;http://blog.csdn.net/guxch/article/details/12162131 ----------------------------------------------------------------------------------- 【接上文“thrift介绍及应用&#xff08;一&#xff09;—介绍”】 六、一个最简单的实例 Thrift文件&#xf…

打游戏的教育意义

夜色已深&#xff0c;一个男孩子还在打游戏。门忽然开了&#xff0c;妈妈走了进来&#xff0c;她把一碗阳春面摆在桌子上。说&#xff1a;"歇息一会儿&#xff0c;趁热把这碗面吃了吧。"孩子嗯了一声&#xff0c;眼睛没有离开屏幕。妈妈生怕打搅孩子&#xff0c;悄悄…

标准评分卡分数计算原理_评分卡的形式、刻度及应用场景

&#xfeff; 看到有伙伴提问&#xff1a;①我们的评分卡做好后&#xff0c;后续的使用策略是什么呀&#xff0c;都有哪些方向&#xff1f; ②评分卡分数切割点如何定&#xff0c;制定的业务逻辑是什么&#xff1f;其实&#xff0c;这个问题不好回答&#xff0c;也好回答。一方…

hexeditor 复制二进制值_MySQL复制全解析 Part 6 MySQL GTID 生命周期

实验环境此次实验的环境如下MySQL 5.7.25Redhat 6.10操作系统账号:mysql数据库复制账号:repl复制格式:基于行的复制通过前面的介绍我们知道MySQL的复制有两种方法基于二进制日志文件位置基于GTID上一节的内容为GTID的格式和存储&#xff0c;这节根据官方文档我们说GTID的生命周…

自动ip的计算机共享打印,局域网内自动获取ip地址怎么设置打印机共享文件夹...

在局域网环境中,为了尽可能地节省办公成本,很多用户都会选择在局域网中架设、部署共享打印机,以便在单位的任何角落处都能方便、自如地进行打印操作。下面是学习啦小编为大家整理的关于局域网内自动获取ip地址怎么设置打印机共享文件夹&#xff0c;一起来看看吧!局域网内自动获…

高级数据分析1代码_用Python进行数据分析,让你一看就会

本书详细介绍利用Python进行操作、处理、清洗和规整数据等方面的具体细节和基本要点。虽然本书的标题是“数据分析”&#xff0c;重点却是Python编程、库&#xff0c;以及用于数据分析的工具。第1章 准备工作第2章 Python语法基础&#xff0c;IPython和Jupyter Notebooks第3章 …

工期日历天计算器_天津实地告诉你:房建项目是怎样保节点,抢工期的?

工程概况天津实地蔷薇花园住宅地块项目共计由24栋单体住宅、2栋配建及地下人防车库组成&#xff0c;其中12层小高层4栋、13层小高层1栋、19栋7层洋房。总建建筑面积为139348.62㎡&#xff0c;地上99348㎡&#xff0c;地下40000㎡&#xff0c;人防面积为14236㎡。工期目标项目施…

测试fps游戏反应速度软件,FPS反应速度提速

静谧无声&#xff0c;生死一瞬&#xff0c;说的就是FPS游戏&#xff0c;没有哪一个种类的游戏可以比拟我们FPS玩家对于反应速度的追求&#xff0c;更快更准哪怕提速只是1毫秒&#xff0c;无数高手之所以为高手就是因为他们可以打出我们看起来不可能完成的击杀&#xff0c;特别是…

html5中单选框被选中把值传给后台_HTML5的表单设计

使用过Delphi的程序员&#xff0c;对Form这个词应该比较熟悉。在Delphi中&#xff0c;Form被翻译为“界面、窗口”&#xff0c;作用是&#xff1a;为用户提供界面&#xff0c;供用户输入信息&#xff0c;向用户展示处理结果。HTML5中也有Form&#xff0c;功能与Delphi中的Form差…

python科赫曲线绘制正方形_Python数据处理从零开始----第四章(可视化)(14)使用seaborn绘制热图...

目录 Python数据处理从零开始----第四章&#xff08;可视化&#xff09;①③多变量绘图 Python数据处理从零开始----第四章&#xff08;可视化&#xff09;&#xff08;14&#xff09;使用seaborn绘制热图 seaborn.heatmapHeat maps显示数字表格数据&#xff0c;其中单元格根据…

Hive的系统架构

一、架构图 二、各组件 用户接口&#xff1a;包括 CLI&#xff08;控制台命令&#xff09;&#xff0c;JDBC/ODBC&#xff0c;WebUI。 CLI&#xff0c;即Shell命令行 JDBC/ODBC 是 Hive 的Java&#xff0c;与使用传统数据库JDBC的方式类似 WebGUI是通过浏览器访问 Hive --…

坐标不显示_Simpack不显示坐标轴方向的解决方法

经常有用户咨询Simpack软件打开模型时&#xff0c;不能显示坐标轴的x、y、z方向&#xff0c;这个问题对建模有很大的影响。本文是兰州交通大学陈龙同学提供的解决方法&#xff0c;供大家参考。使用Simpack软件建模时&#xff0c;会遇到这种情况&#xff1a;比如要创建标记点时&…

th:text为null报错_为vue3.0的学习TS解读高级类型

知识点摘要本节课主要关键词为: 自动类型推断 / 类型断言 / 类型别名(type) / 映射类型(Pick/Record等...) / 条件类型(extends) / 类型推断(infer)自动类型推断(不用你标类型了,ts自己猜)大家现在写ts的时候一定会在每个变量后面都加上类型吧? 但是?现在告诉大家有些情况下你…

Hive与Hadoop的调用关系

一、调用图 二、步骤解析 1、提交sql 交给驱动 2、驱动编译&#xff1a;解析相关的字段表信息 3、去metastore查询相关的信息 返回字段表信息 4、编译返回信息 发给驱动 5、驱动发送一个执行计划 交给执行引擎 6、执行计划 6.1、DDLs 对数据库表的操作的 直接和metastore交互 …

简述计算机文件的命名办法,如何进行文件命名-如何进行文件管理

如何进行文件命名-如何进行文件管理电脑的管理事实上就是文件和文件夹的管理。想要我们的电脑干净整齐&#xff0c;就需要我们正确的进行文件管理。我们知道了文件和文件夹的概念之后&#xff0c;现在我们再来看看单独的文件&#xff0c;认识一下文件的构成以及文件命名和命名规…

网页加载出现没有合适的负载均衡器_分布式必知必会-七层负载和四层负载到底是什么?...

背景我们在使用负载均衡器的时候&#xff0c;往往会听到七层负载或四层负载这两个名词&#xff0c;许多负载均衡软件提供的方式也不同&#xff0c;那么七层和四层区别在哪呢&#xff1f;为什么有的支持有的不支持呢&#xff1f;负载均衡简介负载均衡建立在现有网络结构之上&…

博弈论 斯坦福game theory stanford week 3.2_

title: 博弈论 斯坦福game theory stanford week 3-1 tags: note notebook: 6- 英文课程-15-game theory --- 博弈论 斯坦福game theory stanford week 3-1 习题 第 1 个问题 We say that a game is dominance solvable, if iterative deletion of strictly dominated strategi…

nestjs swagger文档调用需要鉴权的接口

目标 nestjs经常需要设置一些鉴权&#xff08;登录后&#xff09;才能访问的接口&#xff0c;但是生成的swagger文档可以发起接口请求&#xff0c;文档发起的请求默认是不携带登录token的&#xff0c;所以需要移除swagger文档发起请求的守卫拦截。 nestjs守卫拦截设置见另一篇…