Table of Contents

什么是Thrift

架构

什么是RPC框架?

Thrift的协议栈结构

优点

创建一个Thrift服务

Thrift的第一个java小实例


Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。它通过一个代码生成引擎联合了一个软件栈,来创建不同程度的、无缝的跨平台高效服务,可以使用C#、C++(基于POSIX兼容系统)、Cappuccino、Cocoa、Delphi、Erlang、Go、Haskell、Java、Node.js、OCaml、Perl、PHP、Python、Ruby和Smalltalk。虽然它以前是由Facebook开发的,但它现在是Apache软件基金会的开源项目了。该实现被描述在2007年4月的一篇由Facebook发表的技术论文中,该论文现由Apache掌管。

什么是Thrift

https://www.jianshu.com/p/4723ce380b0e


Protobuf是一个语言中立、平台中立,对结构化数据进行序列化的可扩展机制。

我们在开发的时候开发了一个restful web service,就是基于rest的http调用,A系统作为客户端,B系统作为服务器端。A系统可以通过URL的方式携带一些数据去调用B所提供的接口然后返回相应的结果数据。这种方式我们也可以认为是RPC的一种实现方式。对于这种方式我们可以认为是平台独立的、语言独立的,也就是语言中立、平台中立。也就是我们可以用Python编写的客户端去调用Java编写的服务端,因为都是通过URL的方式调用。因为URL相当于契约,URL背后的代码调用者无需关心。

RPC框架调用基本模型:如person.getPersonByName(String name),首先客户端先序列化调用数据,传给服务端,服务端再反序列化提取调用信息,查询客户端所需要的数据,完成之后再序列化结果传回给客户端。客户端再反序列化得到结果。

Apache thrift是一个可伸缩的,并且跨语言的一种服务性的开发,他所完成的功能实际上和protobuf是类似的。简单来说,是Facebook公布的一款开源跨语言的RPC框架。

架构


Thrift包含一套完整的栈来创建客户端和服务端程序。顶层部分是由Thrift定义生成的代码。而服务则由这个文件客户端和处理器代码生成。在生成的代码里会创建不同于内建类型的数据结构,并将其作为结果发送。协议和传输层是运行时库的一部分。有了Thrift,就可以定义一个服务或改变通讯和传输协议,而无需重新编译代码。除了客户端部分之外,Thrift还包括服务器基础设施来集成协议和传输,如阻塞、非阻塞及多线程服务器。栈中作为I/O基础的部分对于不同的语言则有不同的实现。

Thrift支持众多通讯协议:

  • TBinaryProtocol – 一种简单的二进制格式,简单,但没有为空间效率而优化。比文本协议处理起来更快,但更难于调试。
  • TCompactProtocol – 更紧凑的二进制格式,处理起来通常同样高效。
  • TDebugProtocol – 一种人类可读的文本格式,用来协助调试。
  • TDenseProtocol – 与TCompactProtocol类似,将传输数据的元信息剥离。
  • TJSONProtocol – 使用JSON对数据编码。
  • TSimpleJSONProtocol – 一种只写协议,它不能被Thrift解析,因为它使用JSON时丢弃了元数据。适合用脚本语言来解析。

支持的传输协议有:

  • TFileTransport – 该传输协议会写文件。
  • TFramedTransport – 当使用一个非阻塞服务器时,要求使用这个传输协议。它按帧来发送数据,其中每一帧的开头是长度信息。
  • TMemoryTransport – 使用存储器映射输入输出。(Java的实现使用了一个简单的ByteArrayOutputStream。)
  • TSocket – 使用阻塞的套接字I/O来传输。
  • TZlibTransport – 用zlib执行压缩。用于连接另一个传输协议。

Thrift还提供众多的服务器,包括:

  • TNonblockingServer – 一个多线程服务器,它使用非阻塞I/O(Java的实现使用了NIO通道)。TFramedTransport必须跟这个服务器配套使用。
  • TSimpleServer – 一个单线程服务器,它使用标准的阻塞I/O。测试时很有用。
  • TThreadPoolServer – 一个多线程服务器,它使用标准的阻塞I/O。

什么是RPC框架?

https://www.jianshu.com/p/4723ce380b0e


RPC全称为Remote Procedure Call,意为远程过程调用。

假设有两台服务器A,B.A服务器上部署着一个应用a,B服务器上部署着一个应用b,现在a希望能够调用b应用的某个函数(方法),但是二者不在同一个进程内,不能直接调用,就需要通过网络传输,在AB服务器之间建一条网络传输通道,a把参数传过去,b接收到参数调用自己的方法得到结果,再通过网络传回给a。

简单讲就是A通过网络来调用B的过程,这个过程要涉及的东西很多,比如多线程、Socket、序列化反序列化、网络I/O,很复杂。于是牛掰的程序员把这些封装起来做成一套框架供大家使用,就是RPC框架。

thrift通过一个中间语言IDL(接口定义语言)来定义RPC的数据类型和接口,这些内容写在以.thrift结尾的文件中,然后通过特殊的编译器来生成不同语言的代码,以满足不同需要的开发者。比如java开发者,就可以生成java代码,c++开发者可以生成c++代码,生成的代码中不但包含目标语言的接口定义、方法、数据类型,还包含有RPC协议层和传输层的实现代码。

Thrift的协议栈结构


Thrift是一种c/s的架构体系。TServer主要任务是高效的接受客户端请求,并将请求转发给Processor处理。

  • 最上层是用户自行实现的业务逻辑代码;
  • Processor是由thrift编译器自动生成的代码,它封装了从输入数据流中读数据和向数据流中写数据的操作,它的主要工作是:从连接中读取数据,把处理交给用户实现impl,最后把结果写到连接上。
  • TProtocol是用于数据类型解析的,将结构化数据转化为字节流给TTransport进行传输。从TProtocol以下部分是thirft的传输协议和底层I/O通信。
  • TTransport是与底层数据传输密切相关的传输层,负责以字节流方式接收和发送消息体,不关注是什么数据类型。
  • 底层IO负责实际的数据传输,包括socket、文件和压缩数据流等。

优点


Thrift一些已经明确的优点包括:

  • 跟一些替代选择,比如SOAP相比,跨语言序列化的代价更低,因为它使用二进制格式。
  • 它有一个又瘦又干净的库,没有编码框架,没有XML配置文件。
  • 绑定感觉很自然。例如,Java使用java.util.ArrayList<String>;C++使用std::vector<std::string>。
  • 应用层通讯格式与序列化层通讯格式是完全分离的。它们都可以独立修改。
  • 预定义的序列化格式包括:二进制格式、对HTTP友好的格式,以及紧凑的二进制格式。
  • 兼作跨语言文件序列化。
  • 协议使用软版本号机制软件版本管理。Thrift不要求一个中心化的和显式的版本号机制,例如主版本号/次版本号。松耦合的团队可以轻松地控制RPC调用的演进。
  • 没有构建依赖也不含非标准化的软件。不存在不兼容的软件许可证混用的情况。

创建一个Thrift服务


Thrift由C++编写,但可以为众多语言创建代码。要创建一个Thrift服务,必须写一些Thrift文件来描述它,为目标语言生成代码,并且写一些代码来启动服务器及从客户端调用它。

Thrift将由这个描述信息生成独立的代码。例如,在Java里,PhoneType将是Phone类中一个简单的enum。

百度百科:https://baike.baidu.com/item/thrift/3879058

Thrift的第一个java小实例


创建一个服务Hello,创建文件Hello.thrift,代码如下:

namespace java service.demo
service Hello{string helloString(1:string para)
}

终端进入Hello.thrift所在目录,执行命令:

thrift -r -gen java Hello.thrift

发现在当前目录下多了一个gen-java的目录,里面的有一个Hello.java的文件。这个java文件包含Hello服务的接口定义Hello.Iface,以及服务调用的底层通信细节,包括客户端的调用逻辑Hello.Client以及服务端的处理逻辑Hello.Processor

创建一个Maven管理的Java项目,pom.xml中添加相关的依赖,并将Hello.java文件复制到项目中:

<dependency><groupId>org.apache.thrift</groupId><artifactId>libthrift</artifactId><version>0.10.0</version>
</dependency>
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.5</version>
</dependency>

创建HelloServiceImpl实现Hello.Iface接口:

package service.demo;
import org.apache.thrift.TException;public class HelloServiceImpl implements Hello.Iface {public String helloString(String para) throws TException {return "result:"+para;}
}

创建服务端实现代码HelloServiceServer,把HelloServiceImpl作为一个具体的处理器传递给Thrift服务器:

public class HelloServiceServer {/*** 启动thrift服务器*/public static void main(String[] args) {try {System.out.println("服务端开启....");// 1.创建TProcessorTProcessor tprocessor = new Hello.Processor<Hello.Iface>(new HelloServiceImpl());// 2.创建TserverTransportTServerSocket serverTransport = new TServerSocket(9898);// 3.创建TProtocolTBinaryProtocol.Factory factory = new TBinaryProtocol.Factory();TServer.Args tArgs = new TServer.Args(serverTransport);tArgs.processor(tprocessor);tArgs.protocolFactory(factory);// 4.创建Tserver,传入需要的参数,server将以上内容集成在一起TServer server = new TSimpleServer(tArgs);// 5.启动serverserver.serve();}catch (TTransportException e) {e.printStackTrace();}}
}

创建客户端实现代码HelloServiceClient,调用Hello.client访问服务端的逻辑实现:

public class HelloServiceClient {public static void main(String[] args) {System.out.println("客户端启动....");TTransport transport = null;try {transport = new TSocket("localhost", 9898, 30000);// 协议要和服务端一致TProtocol protocol = new TBinaryProtocol(transport);Hello.Client client = new Hello.Client(protocol);transport.open();String result = client.helloString("哈哈");System.out.println(result);} catch (TTransportException e) {e.printStackTrace();} catch (TException e) {e.printStackTrace();} finally {if (null != transport) {transport.close();}}}
}

全部工作完成后,下面来测试一下,先执行服务端main方法,在执行客户端main方法,会在客户端控制台打印出:哈哈

什么是 Thrift(RPC)?一种接口描述语言和二进制通讯协议,用来定义和创建跨语言的服务相关推荐

  1. 跨语言RPC框架Thrift详解

    一. 概念 Apache的Thrift软件框架,是用来进行可伸缩的.跨语言的服务开发,它通过一个代码生成引擎来构建高效.无缝的服务,这些服务能够实现跨语言调度,目前支持的语言有: C++, Java, ...

  2. server如何调用 thrift_一文带你了解 Thrift,一个可伸缩的跨语言 RPC 框架(pinpoint 源码分析系列)...

    Thrift 是什么研究分布式调用链工具pinpoint的时候,在源码里看到了Thrift相关的代码,所以来了兴趣,想研究研究这个框架.Thrift 目前是 Apache 的一个项目,但是它是由fac ...

  3. 跨语言rpc框架Thrift

    RPC 全称 Remote Procedure Call--远程过程调用.RPC技术简单说就是为了解决远程调用服务 的一种技术,使得调用者像调用本地服务一样方便透明 Thrift的定义   Thrif ...

  4. 多语言互通:谷歌发布实体检索模型,涵盖超过100种语言和2000万个实体

    来源:新智元 本文约1500字,建议阅读5分钟 实体链接(Entity linking)通常在自然语言理解和知识图谱中起着关键作用.谷歌AI研究人员近期提出了一种新的技术,在这种技术中,可以将特定语言 ...

  5. thrift RPC接口请求超时

    某次client调用服务端thrift  RPC接口超时导致连接断开,但是server说自己返回数据了,然后client用tcpdump抓包发现没抓到server返回的数据,没抓到表明client没收 ...

  6. 使用Thrift RPC编写程序

    http://dongxicheng.org/search-engine/thrift-rpc/ 1. 概述 本文以C++语言为例介绍了thrift RPC的使用方法,包括对象序列化和反序列化,数据传 ...

  7. 从头开发一个 RPC 是种怎样的体验?

    [CSDN 编者按]对于开发人员来说,调用远程服务就像是调用本地服务一样便捷.尤其是在微服务盛行的今天,了解RPC的原理过程是十分有必要的. 作者 | Alex Ellis       译者 | 弯月 ...

  8. 如何把thrift rpc转换为http

    背景 在平常的业务开发中遇到了两个场景: 1.由于业务用的rpc框架是thrift,代码也是都是用thrift在写,有一天突然接到个需要前端要用http访问接口的需求,于是花了几天时间把所有的thri ...

  9. LinuxC/C++编程基础(24) 使用thrift/rpc开发简单实例(续2)

    写在前面:前面两篇文字已经把thrift/rpc的安装以及服务端的编写叙述了,这里再把客户端的编写加上 一.client.cpp文件实现,如下: #include "../gen-cpp/M ...

最新文章

  1. Docker大行其道—镜像
  2. c# LUA 互通,相关资料收集
  3. ionic常见问题及解决方案
  4. springcloud(一):大话Spring Cloud
  5. javascript 自动化单元测试
  6. 【Verilog】verilog实现奇数次分频
  7. ELK-日志收集工具nxlog
  8. 解压版mysql使用
  9. Android9.0 短信发送和彩信接受流程
  10. 在vue中将数据导出为excel文件file-saver+xlsx+script-loader
  11. matlab中eacf函数,基于MATLAB的切比雪夫I型模拟低通滤波器设计
  12. 集思录REITs基金数据python爬取写入EXCEL表
  13. 基于php鲜花花卉销售商城网站(源码+系统+mysql数据库+Lw文档)
  14. UltraEdit 15 注册码
  15. 团体程序设计天梯赛-习题集部分题解(大牛勿喷)
  16. 如何在 ActiveX 控件中使用字体
  17. 【PostgreSQL】数据表的增删改查
  18. 妻子网购负债30万,丈夫被逼跳楼:别让“伪精致”,毁掉你的人生
  19. iPhone4 来电视频制作 超酷黑色主题,动态壁纸 附高清 性 感mv 上
  20. springboot和sping异同

热门文章

  1. php接口下载图片,php图片下载方法
  2. SpringMVC框架----SpringMVC的自定义类型转换器
  3. Python3 移动文件——合集
  4. linux 环境下的进程间的通信——消息队列传输结构体
  5. 谈谈JavaScript的ECMA5中forEach
  6. HEAP: Free Heap block xxxxxxxx modified at xxxxxxxx after it was freed
  7. 8-2-Listener监听器
  8. android 8 wifi 不稳定,Android 8.0又背锅?网络兼容问题导致WiFi狂掉线
  9. mysql从大到小排序_sql语句时间排序 sql语句按照时间排序
  10. mysql 日志抓取变化_MySQL慢查询日志分析提取【转】