RPC 框架之Thrift入门(一)
📋 个人简介
- 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜
- 📝 个人主页:馆主阿牛🔥
- 🎉 支持我:点赞👍+收藏⭐️+留言📝
- 💬格言:迄今所有人生都大写着失败,但不妨碍我继续向前!🔥

目录
- 📋 个人简介
- 前言
- Thrift简介
- IDL介绍
- IDL语法学习
- 1.基本类型
- 2.struct结构体
- 3.container容器
- 4.service服务
- 5.枚举(enum)
- 6.异常(exception)
- 7.命名空间
- Thrift 编译器安装
- 入门案例
- 业务逻辑
- 服务端
- 客户端
- pom.xml
- 运行
- 结语
前言
随着近些年微服务的盛行,使得服务逐渐模块化,功能化,单个服务仅仅实现某个特定的功能或者模块,因此服务间的调用变得常见且频繁,所以高性能且快速响应的服务调用成了必须去面对的问题,传统的http请求能面对跨语言的问题,但是性能远远无法达到高并发的要求,因此更偏向底层的RPC框架越来越受到青睐,像阿里的Dubbo,谷歌的gRPC,facebook的Thrift等等!本节将学习Thrift这个跨语言的Thrift RPC框架!
Thrift简介
Thrift是一个跨语言的服务部署框架,最初由Facebook于2007年开发,2008年进入Apache开源项目,主要用于各个服务之间的RPC通信,支持跨语言,常用的语言比如C++, Java, Python, PHP, Ruby, Erlang, Perl, C#, JavaScript, Node.js等都支持。(博主也是一名多语言爱好者,因此对Thrift也比较感兴趣,所以在后面,我也会写java,python 的这两种语言的RPC调用。)
IDL介绍
Thrift是一个典型的CS(客户端/服务端)结构,客户端和服务端可以使用不同的语言开发。既然客户端和服务端能使用不同的语言开发,那么一定就要有一种中间语言来关联客户端和服务端的语言,没错,这种语言就是IDL(Interface Description Language)。
IDL 是一种用于定义接口和数据结构的语言,用于描述 Thrift 的服务接口和数据类型。在 Thrift 中使用的是 Thrift 自定义的 IDL 语言,它具有类似于其他接口描述语言的特性。
因此我们需要写IDL,然后使用Thrift编译器将IDL转换为对应的语言,我们开发者只需要实现具体的业务逻辑,无需关注底层逻辑!
IDL语法学习
在学习thrift之前,我们需要先简单的学习一下IDL的语法,很简单,和其他语言结构差不多。
1.基本类型
| 类型 | 解释 |
|---|---|
| bool | 布尔值 |
| byte | 8位有符号整数 |
| i16 | 16位有符号整数 |
| i32 | 32位有符号整数 |
| i64 | 64位有符号整数 |
| double | 64位浮点数 |
| string | UTF-8编码的字符串 |
| binary | 二进制串 |
2.struct结构体
先看例子:
struct Person { // 定义 Person 结构体1: required string name; // 姓名,必选字段2: required i32 age; // 年龄,必选字段3: optional string sex; // 性别,可选字段
}
如上面所示,它类似C语言的结构体,对应java中的Bean,其中required修饰的他的值初始化是必传项。
3.container容器
有三种可用的容器类型:
- list
元素类型为t的有序列表,允许重复。类似于java中的ArrayList。 - set
元素类型为t的无序表,不允许重复。类似于java中的HashSet。 - map<t, t>
键类型为t,值类型为t的键值对,键不允许重复。类似于java中的HashMap。
例如:
struct Test {1: map<string, User> usermap,2: set<i32> intset,3: list<double> doublelist
}
4.service服务
服务的定义方法在语义上等同于面向对象语言中的接口。
service PersonService { // 定义 PersonService 服务接口Person getByName(1: string name); // 根据姓名获取 Person 信息bool save(1: Person person); // 保存 Person 信息
}
5.枚举(enum)
枚举的定义形式和Java的Enum定义差不多,例如:
enum Sex {MALE,FEMALE
}
6.异常(exception)
thrift支持自定义exception,规则和struct一样,如下:
exception RequestException {1: i32 code;2: string reason;
}
7.命名空间
thrift的命名空间相当于Java中的package的意思,主要目的是组织代码。thrift使用关键字namespace定义命名空间,例如:
namespace java com.aniu.service
namespace py example
namespace 后跟的是你要转化的语言以及生成的文件所在的包!
Thrift 编译器安装
写完IDL文件后,我们需要将其转换成对应语言!因此,我们需要先安装Thrift编译器!这里博主用的Windows,macos和Linux自行下载!
网址:https://dlcdn.apache.org/thrift/0.19.0/thrift-0.19.0.exe
下载安装完成后,配置完环境变量,如下图,可查看版本!后序在其他语言例如java中引入maven包时,需要对应版本!

入门案例
这里编写一个简单的入门案例,实现rpc远程过程调用!
定义thrift 文件 person.thrift
namespace java com.aniu.servicestruct Person { // 定义 Person 结构体1: required string name; // 姓名,必选字段2: required i32 age; // 年龄,必选字段3: optional string sex; // 性别,可选字段
}service PersonService { // 定义 PersonService 服务接口Person getByName(1: string name); // 根据姓名获取 Person 信息bool save(1: Person person); // 保存 Person 信息
}
使用
thrift --gen java user.thrift
命令,即可在当前目录下生成gen-java目录,里面即是生成的java代码!


引入对应版本的Maven包
<dependency><groupId>org.apache.thrift</groupId><artifactId>libthrift</artifactId><version>0.19.0</version></dependency>
目录结构如下:

如上图,Person和PersonService即为thrift编译器将IDL转换后生成的java代码。
业务逻辑
PersonService里面有两个接口,我们需要实现接口,在实现类里面写业务逻辑。

package com.aniu.service.impl;import com.aniu.service.Person;
import com.aniu.service.PersonService;
import org.apache.thrift.TException;public class PersonServiceImpl implements PersonService.Iface {@Overridepublic Person getByName(String name) throws TException {return new Person(name,18);}@Overridepublic boolean save(Person person) throws TException {return false;}
}
服务端
package com.aniu.server;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import com.aniu.service.PersonService;
import com.aniu.service.impl.PersonServiceImpl;
public class Server {public static void main(String[] args) {try{// 创建一个新的 Thrift 服务端套接字,监听在端口 9000 上TServerSocket socket = new TServerSocket(9000);// 创建一个 PersonService 的 Processor。Processor 是 Thrift 中用于处理请求的接口,它需要一个实现了 PersonService 接口的对象作为参数。PersonService.Processor<PersonServiceImpl> processor = new PersonService.Processor<>(new PersonServiceImpl());// 创建一个二进制协议工厂对象。Thrift 支持多种协议,如 TBinaryProtocol、TCompactProtocol、TJSONProtocol 等,这里选择的是二进制协议。TBinaryProtocol.Factory factory = new TBinaryProtocol.Factory();// 创建一个 TSimpleServer 的参数对象 args1,并将之前创建的套接字、Processor 和协议工厂设置为其属性。TServer.Args args1 = new TSimpleServer.Args(socket);args1.processor(processor);args1.protocolFactory(factory);// 使用之前设置好的参数创建 TSimpleServer 对象TSimpleServer tSimpleServer = new TSimpleServer(args1);// 开始执行 TSimpleServer,开始监听并处理客户端的请求。tSimpleServer.serve();}catch (Exception e){System.out.println(e);}}
}
客户端
import com.aniu.service.PersonService;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.transport.TSocket;
public class Client {public static void main(String[] args) {try{// 创建一个 Thrift 的套接字对象,连接到在本地主机(localhost)的9000端口上运行的 Thrift 服务。TSocket socket = new TSocket("localhost", 9000);// 创建一个使用二进制协议的实例,该协议用于在客户端和服务器之间传输数据。TBinaryProtocol protocol = new TBinaryProtocol(socket);// 创建一个Thrift 客户端实例,它使用前面创建的二进制协议实例进行通信。PersonService.Client client = new PersonService.Client(protocol);// 打开与服务器端的连接,通过客户端对象(client)进行远程过程调用(RPC)或其他通信操作socket.open();// RPC 调用Person person = client.getByName("aniu");System.out.println(person);}catch (Exception e){System.out.println(e);}}
}
pom.xml
<dependencies><dependency><groupId>org.apache.thrift</groupId><artifactId>libthrift</artifactId><version>0.19.0</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.5</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.30</version><scope>compile</scope></dependency><dependency><groupId>jakarta.annotation</groupId><artifactId>jakarta.annotation-api</artifactId><version>1.3.5</version><scope>compile</scope></dependency></dependencies>
运行
先启动服务端,再启动客户端,即可实现RPC调用!

结语
本节实现了一个简单的案例,但对于thrift的服务端如何创建的,客户端如何调用没有具体讲解,基本都在注释里,下一篇博文来讲解原理以及实现跨语言RPC调用!
相关文章:
RPC 框架之Thrift入门(一)
📋 个人简介 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜📝 个人主页:馆主阿牛🔥🎉 支持我:点赞👍收藏⭐️留言Ὅ…...
【C++】运算符重载 ⑥ ( 一元运算符重载 | 后置运算符重载 | 前置运算符重载 与 后置运算符重载 的区别 | 后置运算符重载添加 int 占位参数 )
文章目录 一、后置运算符重载1、前置运算符重载 与 后置运算符重载 的区别2、后置运算符重载添加 int 占位参数 上 2 2 2 篇博客 【C】运算符重载 ④ ( 一元运算符重载 | 使用 全局函数 实现 前置 自增运算符重载 | 使用 全局函数 实现 前置 - - 自减运算符重载 )【C】运算符…...
538. 把二叉搜索树转换为累加树
题目描述 给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。 提醒一下,二叉搜索树满足下列约束…...
java8日期时间工具类
【README】 1)本文总结了java8中日期时间常用工具方法;包括: 日期时间对象格式化为字符串;日期时间字符串解析为日期时间对象;日期时间对象转换; 转换过程中,需要注意的是: Instan…...
算法-动态规划/trie树-单词拆分
算法-动态规划/trie树-单词拆分 1 题目概述 1.1 题目出处 https://leetcode.cn/problems/word-break/description/?envTypestudy-plan-v2&envIdtop-interview-150 1.2 题目描述 2 动态规划 2.1 解题思路 dp[i]表示[0, i)字符串可否构建那么dp[i]可构建的条件是&…...
React框架核心原理
一、整体架构 三大核心库与对应的组件 history -> react-router -> react-router-dom react-router 可视为react-router-dom 的核心,里面封装了<Router>,<Route>,<Switch>等核心组件,实现了从路由的改变到组件的更新…...
python-pytorch 利用pytorch对堆叠自编码器进行训练和验证
利用pytorch对堆叠自编码器进行训练和验证 一、数据生成二、定义自编码器模型三、训练函数四、训练堆叠自编码器五、将已训练的自编码器级联六、微调整个堆叠自编码器 一、数据生成 随机生成一些数据来模拟训练和验证数据集: import torch# 随机生成数据 n_sample…...
制作 3 档可调灯程序编写
PWM 0~255 可以将数据映射到0 75 150 225 尽可能均匀电压间隔...
源码分享-M3U8数据流ts的AES-128解密并合并---GoLang实现
之前使用C语言实现了一次,见M3U8数据流ts的AES-128解密并合并。 学习了Go语言后,又用Go重新实现了一遍。源码如下,无第三方库依赖。 package mainimport ("crypto/aes""crypto/cipher""encoding/binary"&quo…...
CSDN Q: “这段代码算是在STC89C52RC51单片机上完成PWM呼吸灯了吗?“
这是 CSDN上的一个问题 这段代码算是在STC89C52RC51单片机上完成PWM呼吸灯了吗,还是说得用上定时器和中断函数#include <regx52.h> 我个人认为: 效果上来说, 是的! 码以 以Time / 100-Time 调 Duty, 而 for i loop成 Period, 加上延时, 实现了 PWM周期, 虽然…...
Linux系统编程系列之线程池
Linux系统编程系列(16篇管饱,吃货都投降了!) 1、Linux系统编程系列之进程基础 2、Linux系统编程系列之进程间通信(IPC)-信号 3、Linux系统编程系列之进程间通信(IPC)-管道 4、Linux系统编程系列之进程间通信-IPC对象 5、Linux系统…...
Linux CentOS7 vim多文件与多窗口操作
窗口是可视化的分割区域。Windows中窗口的概念与linux中基本相同。连接xshell就是在Windows中新建一个窗口。而vim打开一个文件默认创建一个窗口。同时,Vim打开一个文件也就会建立一个缓冲区,打开多个文件就会创建多个缓冲区。 本文讨论vim中打开多个文…...
SPI 通信协议
1. SPI通信 1. 什么是SPI通信协议 2. SPI的通信过程 在一开始会先把发送缓冲器的数据(8位)。一次性放到移位寄存器里。 移位寄存器会一位一位发送出去。但是要先放到锁存器里。然后从机来读取。从机的过程也一样。当移位寄存器的数据全部发送完。其实…...
【图像处理】使用各向异性滤波器和分割图像处理从MRI图像检测脑肿瘤(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
5个适合初学者的初级网络安全工作,网络安全就业必看
前言 网络安全涉及保护计算机系统、网络和数据免受未经授权的访问、破坏和盗窃 - 防止数字活动和数据访问的中断 - 同时也保护用户的资产和隐私。鉴于公共事业、医疗保健、金融以及联邦政府等行业的网络犯罪攻击不断升级,对网络专业人员的需求很高,这并…...
Kafka核心原理
1、Topic的分片和副本机制 分片作用: 解决单台节点容量有限的问题,节点多,效率提升,吞吐量提升。通过分片,将一个大的容器分解为多个小的容器,分布在不同的节点上,从而实现分布式存储。 分片…...
探秘前后端开发世界:猫头虎带你穿梭编程的繁忙街区,解锁全栈之路
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
洛谷_分支循环
p2433 问题 5 甲列火车长 260 米,每秒行 12 米;乙列火车长220 米,每秒行 20 米,两车相向而行,从两车车头相遇时开始计时,多长时间后两车车尾相离?已知答案是整数。 计算方式:两车车…...
MySQL数据库入门到精通——进阶篇(3)
黑马程序员 MySQL数据库入门到精通——进阶篇(3) 1. 锁1.1 锁-介绍1.2 锁-全局锁1.3 锁-表级锁1.3.1 表级锁-表锁1.3.2 表级锁元数据锁( meta data lock,MDL)1.3.3 表级锁-意向锁1.3.4 表级锁意向锁测试 1.4 锁-行级锁1.4.1 行级锁-行锁1.4.2…...
Mind Map:大语言模型中的知识图谱提示激发思维图10.1+10.2
知识图谱提示激发思维图 摘要介绍相关工作方法第一步:证据图挖掘第二步:证据图聚合第三步:LLM Mind Map推理 实验实验设置医学问答长对话问题使用KG的部分知识生成深入分析 总结 摘要 LLM通常在吸收新知识的能力、generation of hallucinati…...
微服务架构:使用Docker+Kubernetes部署应用
微服务架构:使用DockerKubernetes部署应用 大家好,我是欧阳瑞(Rich Own)。今天想和大家聊聊微服务架构以及如何使用Docker和Kubernetes进行部署。作为一个全栈开发者,我经历过单体应用到微服务的转型,深刻体…...
基于DGX OpenClaw Stack构建本地AI智能体:从硬件调优到生产部署
1. 项目概述:一站式本地AI智能体栈如果你和我一样,对把大语言模型(LLM)真正“养”在自己的硬件上,构建一个功能完整、数据私有的智能助手有执念,那么你很可能已经踩过不少坑了。从选模型、搭服务、配工具链…...
【AI原生架构黄金法则】:SITS 2026现场实录的7条反直觉设计铁律(仅限首批参会专家内部流出)
AI原生应用架构设计:SITS 2026技术专家实战经验分享 更多请点击: https://intelliparadigm.com 第一章:SITS 2026现场共识与AI原生架构范式跃迁 在SITS 2026全球智能系统技术峰会上,来自37个国家的架构师、AI平台工程师与标准化组…...
服务器运维与DevOps融合:迈向智能化运维的新纪元
在数字化浪潮席卷全球的今天,企业对IT基础设施的依赖程度日益加深,服务器运维作为支撑业务连续性和系统稳定性的核心环节,正面临前所未有的挑战与机遇。传统运维模式依赖人工干预、响应滞后、效率低下,已难以满足现代业务快速迭代…...
Watercolor风格在MJ中被严重低估的3个底层能力:纸基模拟、颜料扩散建模、干湿叠加逻辑(Adobe资深插画师联合验证)
更多请点击: https://intelliparadigm.com 第一章:Watercolor风格在MJ中被严重低估的3个底层能力:纸基模拟、颜料扩散建模、干湿叠加逻辑(Adobe资深插画师联合验证) 纸基模拟:不只是纹理,而是…...
【PyTorch实战】从零构建Prototypical Network:小样本图像分类的度量学习核心
1. 小样本学习与Prototypical Network基础 当你第一次听说"小样本学习"时,可能会觉得这是个遥不可及的高深概念。其实它的核心思想很简单:就像人类能通过少量例子快速学习新事物一样,让AI模型也具备这种能力。想象一下,…...
规则驱动流程引擎:告别if-else,构建灵活业务自动化核心
1. 项目概述:一个规则驱动的流程引擎最近在梳理一些业务自动化需求时,我又把目光投向了规则引擎和流程编排这个老话题。无论是电商的风控审核、金融的信贷审批,还是内容平台的自动化运营,我们总在重复一个模式:定义一堆…...
告别编译警告!MDK AC6编译器下STM32Cube FreeRTOS工程的__packed等语法适配指南
ARM Compiler v6下STM32Cube FreeRTOS工程的零警告优化实战 当你从ARM Compiler v5切换到v6时,可能会发现原本运行良好的STM32CubeMX生成的FreeRTOS工程突然冒出几十个编译警告。这些黄色的小三角虽然不会阻止程序编译,但对于追求代码质量的开发者来说&a…...
降AI提示词大全!10个prompt让AI输出人类味+嘎嘎降AI兜底!
降AI提示词大全!10个prompt让AI输出人类味嘎嘎降AI兜底! 用 ChatGPT、DeepSeek、Kimi、豆包写论文最大的痛是:写得快但被检测判 AI、改起来比自己写还累。其实在写作环节就能预防一部分 AI 痕迹,靠的是会写降 AI 提示词。 这篇先给…...
008、RISC-V在TinyML中的崛起与优势
008、RISC-V在TinyML中的崛起与优势 从一块“变砖”的开发板说起 去年冬天,我在调试一个基于Cortex-M4的智能传感器节点。项目要求将唤醒词检测模型塞进32KB的SRAM里,功耗要控制在50μA以下。折腾了两周,模型量化、算子裁剪、甚至手写汇编优化了部分矩阵运算——终于跑通了…...
