apachethrift系列详解-概述与入门

sea520 sea520     2023-04-28     359

关键词:

前言
Thrift是一个轻量级、跨语言的远程服务调用框架,最初由Facebook开发,后面进入Apache开源项目。它通过自身的IDL中间语言, 并借助代码生成引擎生成各种主流语言的RPC服务端/客户端模板代码。

Thrift支持多种不同的编程语言,包括C++、Java、Python、PHP、Ruby等,本系列主要讲述基于Java语言的Thrift的配置方式和具体使用。

正文
Thrift的技术栈
Thrift对软件栈的定义非常的清晰, 使得各个组件能够松散的耦合, 针对不同的应用场景, 选择不同是方式去搭建服务。

 

Thrift软件栈分层从下向上分别为:传输层(Transport Layer)、协议层(Protocol Layer)、处理层(Processor Layer)和服务层(Server Layer)。

传输层(Transport Layer):传输层负责直接从网络中读取和写入数据,它定义了具体的网络传输协议;比如说TCP/IP传输等。

协议层(Protocol Layer):协议层定义了数据传输格式,负责网络传输数据的序列化和反序列化;比如说JSON、XML、二进制数据等。

处理层(Processor Layer):处理层是由具体的IDL(接口描述语言)生成的,封装了具体的底层网络传输和序列化方式,并委托给用户实现的Handler进行处理。

服务层(Server Layer):整合上述组件,提供具体的网络线程/IO服务模型,形成最终的服务。

Thrift的特性
(一) 开发速度快
通过编写RPC接口Thrift IDL文件,利用编译生成器自动生成服务端骨架(Skeletons)和客户端桩(Stubs)。从而省去开发者自定义和维护接口编解码、消息传输、服务器多线程模型等基础工作。

服务端:只需要按照服务骨架即接口,编写好具体的业务处理程序(Handler)即实现类即可。
客户端:只需要拷贝IDL定义好的客户端桩和服务对象,然后就像调用本地对象的方法一样调用远端服务。
(二) 接口维护简单
通过维护Thrift格式的IDL(接口描述语言)文件(注意写好注释),即可作为给Client使用的接口文档使用,也自动生成接口代码,始终保持代码和文档的一致性。且Thrift协议可灵活支持接口的可扩展性。

(三) 学习成本低
因为其来自Google Protobuf开发团队,所以其IDL文件风格类似Google Protobuf,且更加易读易懂;特别是RPC服务接口的风格就像写一个面向对象的Class一样简单。

初学者只需参照:http://thrift.apache.org/,一个多小时就可以理解Thrift IDL文件的语法使用。

(四) 多语言/跨语言支持
Thrift支持C++、 Java、Python、PHP、Ruby、Erlang、Perl、Haskell、C#、Cocoa、JavaScript、Node.js、Smalltalk等多种语言,即可生成上述语言的服务器端和客户端程序。

对于我们经常使用的Java、PHP、Python、C++支持良好,虽然对iOS环境的Objective-C(Cocoa)支持稍逊,但也完全满足我们的使用要求。

(五) 稳定/广泛使用
Thrift在很多开源项目中已经被验证是稳定和高效的,例如Cassandra、Hadoop、HBase等;国外在Facebook中有广泛使用,国内包括百度、美团小米、和饿了么等公司。

 

Thrift的数据类型
Thrift 脚本可定义的数据类型包括以下几种类型:

基本类型:
  bool: 布尔值
  byte: 8位有符号整数
  i16: 16位有符号整数
  i32: 32位有符号整数
  i64: 64位有符号整数
  double: 64位浮点数
  string: UTF-8编码的字符串
  binary: 二进制串
结构体类型:
  struct: 定义的结构体对象
容器类型:
  list: 有序元素列表
  set: 无序无重复元素集合
  map: 有序的key/value集合
异常类型:
  exception: 异常类型
服务类型:
  service: 具体对应服务的类
Thrift的协议
Thrift可以让用户选择客户端与服务端之间传输通信协议的类别,在传输协议上总体划分为文本(text)和二进制(binary)传输协议。为节约带宽,提高传输效率,一般情况下使用二进制类型的传输协议为多数,有时还会使用基于文本类型的协议,这需要根据项目/产品中的实际需求。常用协议有以下几种:

TBinaryProtocol:二进制编码格式进行数据传输
TCompactProtocol:高效率的、密集的二进制编码格式进行数据传输
TJSONProtocol: 使用JSON文本的数据编码协议进行数据传输
TSimpleJSONProtocol:只提供JSON只写的协议,适用于通过脚本语言解析
Thrift的传输层
常用的传输层有以下几种:

TSocket:使用阻塞式I/O进行传输,是最常见的模式
TNonblockingTransport:使用非阻塞方式,用于构建异步客户端
TFramedTransport:使用非阻塞方式,按块的大小进行传输,类似于Java中的NIO
Thrift的服务端类型
TSimpleServer:单线程服务器端,使用标准的阻塞式I/O
TThreadPoolServer:多线程服务器端,使用标准的阻塞式I/O
TNonblockingServer:单线程服务器端,使用非阻塞式I/O
THsHaServer:半同步半异步服务器端,基于非阻塞式IO读写和多线程工作任务处理
TThreadedSelectorServer:多线程选择器服务器端,对THsHaServer在异步IO模型上进行增强
Thrift入门示例
(一) 编写Thrift IDL文件
a). 下载0.10.0的Thrift IDL编译器,下载地址:http://thrift.apache.org/docs/install。 通过编译生成器生成.java接口的类文件。

 

b). 下载Windows安装环境的.exe文件,将thrift.exe的路径加入环境变量中。在Idea上安装Thrift编辑插件。

 

c). 编写hello.thrift的IDL文件:

service HelloWorldService
string say(1: string username)


d). 使用代码生成工具生成代码,执行以下命令:

thrift -gen java hello.thrift
1
e). 由于未指定代码生成的目标目录,生成的类文件默认存放在gen-java目录下。这里生成一个HelloWorldService.java类文件,文件大小超过数千行,下面截取一部分核心代码。

public class HelloWorldService
public interface Iface
public String say(String username) throws org.apache.thrift.TException;

public interface AsyncIface
public void say(String username, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws org.apache.thrift.TException;

public static class Client extends org.apache.thrift.TServiceClient implements Iface
public static class Factory implements org.apache.thrift.TServiceClientFactory<Client>
public Factory()

public Client getClient(org.apache.thrift.protocol.TProtocol prot)
return new Client(prot);

public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot)
return new Client(iprot, oprot);

public Client(org.apache.thrift.protocol.TProtocol prot)
super(prot, prot);

public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot)
super(iprot, oprot);

public String say(String username) throws org.apache.thrift.TException
send_say(username);
return recv_say();

// 省略.....

public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface
public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient>
private org.apache.thrift.async.TAsyncClientManager clientManager;
private org.apache.thrift.protocol.TProtocolFactory protocolFactory;

public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory)
this.clientManager = clientManager;
this.protocolFactory = protocolFactory;

public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport)
return new AsyncClient(protocolFactory, clientManager, transport);

public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport)
super(protocolFactory, clientManager, transport);

public void say(String username, org.apache.thrift.async.AsyncMethodCallback<String> resultHandler) throws org.apache.thrift.TException
checkReady();
say_call method_call = new say_call(username, resultHandler, this, ___protocolFactory, ___transport);
this.___currentMethod = method_call;
___manager.call(method_call);

// 省略.....

// 省略.....


对于开发人员而言,使用原生的Thrift框架,仅需要关注以下四个核心内部接口/类:Iface, AsyncIface, Client和AsyncClient。

Iface:服务端通过实现HelloWorldService.Iface接口,向客户端的提供具体的同步业务逻辑。
AsyncIface:服务端通过实现HelloWorldService.Iface接口,向客户端的提供具体的异步业务逻辑。
Client:客户端通过HelloWorldService.Client的实例对象,以同步的方式访问服务端提供的服务方法。
AsyncClient:客户端通过HelloWorldService.AsyncClient的实例对象,以异步的方式访问服务端提供的服务方法。
(二) 新建Maven工程
a). 新建maven工程,引入thrift的依赖,这里使用的是版本0.10.0。

<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.10.0</version>
</dependency>

b). 将生成类的HelloWorldService.java源文件拷贝进项目源文件目录中,并实现HelloWorldService.Iface的定义的say()方法。

HelloWorldServiceImpl.java

public class HelloWorldServiceImpl implements HelloWorldService.Iface
@Override
public String say(String username) throws TException
return "Hello " + username;



c). 服务器端程序编写:

SimpleServer.java

public class SimpleServer
public static void main(String[] args) throws Exception
ServerSocket serverSocket = new ServerSocket(ServerConfig.SERVER_PORT);
TServerSocket serverTransport = new TServerSocket(serverSocket);
HelloWorldService.Processor processor =
new HelloWorldService.Processor<HelloWorldService.Iface>(new HelloWorldServiceImpl());

TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory();
TSimpleServer.Args tArgs = new TSimpleServer.Args(serverTransport);
tArgs.processor(processor);
tArgs.protocolFactory(protocolFactory);

// 简单的单线程服务模型 一般用于测试
TServer tServer = new TSimpleServer(tArgs);
System.out.println("Running Simple Server");
tServer.serve();



d). 客户端程序编写:

SimpleClient.java

public class SimpleClient
public static void main(String[] args)
TTransport transport = null;
try
transport = new TSocket(ServerConfig.SERVER_IP, ServerConfig.SERVER_PORT, ServerConfig.TIMEOUT);
TProtocol protocol = new TBinaryProtocol(transport);
HelloWorldService.Client client = new HelloWorldService.Client(protocol);
transport.open();

String result = client.say("Leo");
System.out.println("Result =: " + result);
catch (TException e)
e.printStackTrace();
finally
if (null != transport)
transport.close();





e). 运行服务端程序,服务端在指定端口监听客户端的连接请求,控制台输出启动日志:

 

f). 运行客户端程序,客户端通过网络请求HelloWorldService的say()方法的具体实现,控制台输出返回结果:

 

这里使用的一个基于单线程同步的简单服务模型,一般仅用于入门学习和测试!

总结
本文对Thrift的概念做了相关介绍,体验了一番thrift程序如何编写!
————————————————

原文链接:https://blog.csdn.net/baidu_22254181/article/details/82814489

elasticsearch使用指南系列

ElasticSearch使用指南如下:1、ElasticSearchClient详解2、Elasticsearch文档读写模型实现原理3、ElasticsearchDocumentIndexAPI详解、原理与示例4、ElasticsearchDocumentGetAPI详解、原理与示例5、ElasticsearchDocumentDeleteAPI详解、原理与示例6、Elasticsear... 查看详情

大数据入门-大数据技术概述

目录大数据入门系列文章1.大数据入门-大数据是什么一、概念二、技术详解1.基础架构:Hadoop2.分布式文件系统:HDFS3.数据仓库:Hive4.存储引擎:Kudu5.分布式数据库:HBase6.实时框架:Flink三、其他大数据入... 查看详情

大数据入门-大数据技术概述

目录大数据入门系列文章1.大数据入门-大数据是什么2.大数据入门-大数据技术概述(一)一、简介二、技术详解1.分布式协调服务:Zookeeper2.分布式资源管理器:Yarn3.计算引擎:Spark4.查询引擎:Impala5.分布式消息系统&... 查看详情

apachethrift系列详解-序列化机制(代码片段)

前言Thrift支持二进制,压缩格式,以及json格式数据的序列化和反序列化。开发人员可以更加灵活的选择协议的具体形式。协议是可自由扩展的,新版本的协议,完全兼容老的版本!正文数据交换格式简介当前流行的数据交换格... 查看详情

springmvc入门系列篇3:@requestmapping&@requestheader&@cookievalue详解与rest风格请求(代码片段)

一、@RequestMapping1.@RequestMappingvalue:value属性可以用来设置请求路径,值是一个字符串数组,可以设置成多个路径共同访问一个方法,下面代码就是first、second请求共同访问show方法。@RequestMapping(value="/first","/second")publ... 查看详情

canoe入门系列---下载安装及各选项卡详解

CANOE入门系列下载安装及各模块详解CANOE入门系列前言一、CANoe的下载安装二、模块介绍1.CANoe主界面2.File界面3.HOME功能区4.Analysis功能区5.Simulation功能区(核心)6.Test功能7.Diagnostics功能区8.Environment功能区9.Hardware功能区10.Too... 查看详情

❤超强超详细|redis入门详解(代码片段)

...Redis6安装与使用三、常用五大数据类型四、Redis6配置文件详解五、Redis6的发布和订阅六、Redis6新数据类型七、Jedis操作Redis6八、Redis6与SpringBoot整合九、Redis6的事务操作十、Reids6持久化十一、Redis6的主从复制十二、Reids集群十三、R... 查看详情

zookeeper入门系列:概述

zookeeper可谓是目前使用最广泛的分布式组件了。其功能和职责单一,但却非常重要。在现今这个年代,介绍zookeeper的书和文章可谓多如牛毛,本人不才,试图通过自己的理解来介绍zookeeper,希望通过一个初学者的视角来学习zookee... 查看详情

《c#零基础入门之百识百例》(八十三)系统类arraylist数组列表详解--代码示例

...素3.5其他方法总结前言本文属于C#零基础入门之百识百例系列文章。此系列文章旨在为学习C#语言的童鞋提供一套系统的学习路径。此系列文章都会通过【知识点】【练习题】的形式呈现。有任何问题,你都可以通过评 查看详情

[pytorch系列-61]:循环神经网络-中文新闻文本分类详解-3-cnn网络训练与评估代码详解(代码片段)

...试方法的定义6.2开始测试第1章预备知识1.1业务概述[Pytorch系列-59]:循环神经网络-中文新闻文本分类详解-1-业务目标分析与总体架构_文火冰糖(王文兵)的博客-CSDN博客https://blog.csdn.net/HiWangWenBing/article/details/1217567441.2... 查看详情

ros从入门到精通系列ros系统整体架构详解(下)

 目录 ​​​​​​​​二、理解ROS计算图级2.1节点(Node)2.2主题(Topic) 查看详情

5g系列mac(mediumaccesscontrol)协议详解

文章目录NRMAC协议详解一、MAC概述1.1MAC层主要功能1.2MAC提供的服务1.3LTEMAC与5GMAC比较二、MAC实体三、MACPDU介绍3.1MACPDU(transparentMAC)3.2MACPDU(RandomAccessResponse)3.3MACPDU(othersincludingDL-SCHandUL-SCH)3.4MACsubheader四、波束失败检测五、随机 查看详情

5g系列mac(mediumaccesscontrol)协议详解

文章目录NRMAC协议详解一、MAC概述1.1MAC层主要功能1.2MAC提供的服务1.3LTEMAC与5GMAC比较二、MAC实体三、MACPDU介绍3.1MACPDU(transparentMAC)3.2MACPDU(RandomAccessResponse)3.3MACPDU(othersincludingDL-SCHandUL-SCH)3.4MACsubheader四、波束失败检测五、随机 查看详情

重识nginx-系列导读

文章目录Nginx初始Nginx基础架构Http模块详解反向代理与负载均衡Nginx的系统层性能优化源码角度深入使用Nginx与OpenRestyNginx初始重识Nginx-01Nginx主要应用场景及版本概述重识Nginx-02手把手教你编译适合自己的nginx1.22.0Nginx基础架构Http... 查看详情

[pytorch系列-33]:数据集-torchvision与cifar10详解(代码片段)

作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客 本文网址:https://blog.csdn.net/HiWangWenBing/article/details/121055970目录第1章 TorchVision概述1.1 TorchVision1.2 TorchVision的安装1.3 Torc 查看详情

推荐系统从入门到入门——基于mapreuduce与spark的分布式推荐系统构建

    本系列博客总结了不同框架、不同算法、不同界面的推荐系统,完整阅读需要大量时间(又臭又长),建议根据目录选择需要的内容查看,欢迎讨论与指出问题。目录系列文章梗概系列文章目录三、MapRed... 查看详情

ros从入门到精通系列ros系统整体架构详解(上)

目录一、理解ROS文件系统级1.1 Catkin编译系统1.1.1Catkin特点1.1.2Catkin编译原理 查看详情

ivx低代码平台系列详解--系统架构

写在前面ivx动手尝试电梯:ivx在线编辑器iVX系列教程持续更新中系列文章可看:iVX低代码平台系列详解–概述篇(一)iVX低代码平台系列详解–概述篇(二)iVX低代码平台系列详解–概述篇(三)一、前后端分离架构概览:前台部... 查看详情