当前位置: 首页 > news >正文

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布尔值
byte8位有符号整数
i1616位有符号整数
i3232位有符号整数
i6464位有符号整数
double64位浮点数
stringUTF-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入门(一)

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…...

【C++】运算符重载 ⑥ ( 一元运算符重载 | 后置运算符重载 | 前置运算符重载 与 后置运算符重载 的区别 | 后置运算符重载添加 int 占位参数 )

文章目录 一、后置运算符重载1、前置运算符重载 与 后置运算符重载 的区别2、后置运算符重载添加 int 占位参数 上 2 2 2 篇博客 【C】运算符重载 ④ ( 一元运算符重载 | 使用 全局函数 实现 前置 自增运算符重载 | 使用 全局函数 实现 前置 - - 自减运算符重载 )【C】运算符…...

538. 把二叉搜索树转换为累加树

题目描述 给出二叉 搜索 树的根节点&#xff0c;该树的节点值各不相同&#xff0c;请你将其转换为累加树&#xff08;Greater Sum Tree&#xff09;&#xff0c;使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。 提醒一下&#xff0c;二叉搜索树满足下列约束…...

java8日期时间工具类

【README】 1&#xff09;本文总结了java8中日期时间常用工具方法&#xff1b;包括&#xff1a; 日期时间对象格式化为字符串&#xff1b;日期时间字符串解析为日期时间对象&#xff1b;日期时间对象转换&#xff1b; 转换过程中&#xff0c;需要注意的是&#xff1a; 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 的核心&#xff0c;里面封装了<Router>&#xff0c;<Route>&#xff0c;<Switch>等核心组件,实现了从路由的改变到组件的更新…...

python-pytorch 利用pytorch对堆叠自编码器进行训练和验证

利用pytorch对堆叠自编码器进行训练和验证 一、数据生成二、定义自编码器模型三、训练函数四、训练堆叠自编码器五、将已训练的自编码器级联六、微调整个堆叠自编码器 一、数据生成 随机生成一些数据来模拟训练和验证数据集&#xff1a; import torch# 随机生成数据 n_sample…...

制作 3 档可调灯程序编写

PWM 0~255 可以将数据映射到0 75 150 225 尽可能均匀电压间隔...

源码分享-M3U8数据流ts的AES-128解密并合并---GoLang实现

之前使用C语言实现了一次&#xff0c;见M3U8数据流ts的AES-128解密并合并。 学习了Go语言后&#xff0c;又用Go重新实现了一遍。源码如下&#xff0c;无第三方库依赖。 package mainimport ("crypto/aes""crypto/cipher""encoding/binary"&quo…...

CSDN Q: “这段代码算是在STC89C52RC51单片机上完成PWM呼吸灯了吗?“

这是 CSDN上的一个问题 这段代码算是在STC89C52RC51单片机上完成PWM呼吸灯了吗&#xff0c;还是说得用上定时器和中断函数#include <regx52.h> 我个人认为: 效果上来说, 是的! 码以 以Time / 100-Time 调 Duty, 而 for i loop成 Period, 加上延时, 实现了 PWM周期, 虽然…...

Linux系统编程系列之线程池

Linux系统编程系列&#xff08;16篇管饱&#xff0c;吃货都投降了&#xff01;&#xff09; 1、Linux系统编程系列之进程基础 2、Linux系统编程系列之进程间通信(IPC)-信号 3、Linux系统编程系列之进程间通信(IPC)-管道 4、Linux系统编程系列之进程间通信-IPC对象 5、Linux系统…...

Linux CentOS7 vim多文件与多窗口操作

窗口是可视化的分割区域。Windows中窗口的概念与linux中基本相同。连接xshell就是在Windows中新建一个窗口。而vim打开一个文件默认创建一个窗口。同时&#xff0c;Vim打开一个文件也就会建立一个缓冲区&#xff0c;打开多个文件就会创建多个缓冲区。 本文讨论vim中打开多个文…...

SPI 通信协议

1. SPI通信 1. 什么是SPI通信协议 2. SPI的通信过程 在一开始会先把发送缓冲器的数据&#xff08;8位&#xff09;。一次性放到移位寄存器里。 移位寄存器会一位一位发送出去。但是要先放到锁存器里。然后从机来读取。从机的过程也一样。当移位寄存器的数据全部发送完。其实…...

【图像处理】使用各向异性滤波器和分割图像处理从MRI图像检测脑肿瘤(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

5个适合初学者的初级网络安全工作,网络安全就业必看

前言 网络安全涉及保护计算机系统、网络和数据免受未经授权的访问、破坏和盗窃 - 防止数字活动和数据访问的中断 - 同时也保护用户的资产和隐私。鉴于公共事业、医疗保健、金融以及联邦政府等行业的网络犯罪攻击不断升级&#xff0c;对网络专业人员的需求很高&#xff0c;这并…...

Kafka核心原理

1、Topic的分片和副本机制 分片作用&#xff1a; 解决单台节点容量有限的问题&#xff0c;节点多&#xff0c;效率提升&#xff0c;吞吐量提升。通过分片&#xff0c;将一个大的容器分解为多个小的容器&#xff0c;分布在不同的节点上&#xff0c;从而实现分布式存储。 分片…...

探秘前后端开发世界:猫头虎带你穿梭编程的繁忙街区,解锁全栈之路

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

洛谷_分支循环

p2433 问题 5 甲列火车长 260 米&#xff0c;每秒行 12 米&#xff1b;乙列火车长220 米&#xff0c;每秒行 20 米&#xff0c;两车相向而行&#xff0c;从两车车头相遇时开始计时&#xff0c;多长时间后两车车尾相离&#xff1f;已知答案是整数。 计算方式&#xff1a;两车车…...

MySQL数据库入门到精通——进阶篇(3)

黑马程序员 MySQL数据库入门到精通——进阶篇&#xff08;3&#xff09; 1. 锁1.1 锁-介绍1.2 锁-全局锁1.3 锁-表级锁1.3.1 表级锁-表锁1.3.2 表级锁元数据锁( meta data lock&#xff0c;MDL)1.3.3 表级锁-意向锁1.3.4 表级锁意向锁测试 1.4 锁-行级锁1.4.1 行级锁-行锁1.4.2…...

Mind Map:大语言模型中的知识图谱提示激发思维图10.1+10.2

知识图谱提示激发思维图 摘要介绍相关工作方法第一步&#xff1a;证据图挖掘第二步&#xff1a;证据图聚合第三步&#xff1a;LLM Mind Map推理 实验实验设置医学问答长对话问题使用KG的部分知识生成深入分析 总结 摘要 LLM通常在吸收新知识的能力、generation of hallucinati…...

在Ubuntu 22.04上为你的J-Link适配OpenOCD:从源码编译到成功连接实战记录

在Ubuntu 22.04上为J-Link适配OpenOCD&#xff1a;从源码编译到调试连接全流程解析 当你在Ubuntu 22.04环境下进行嵌入式开发时&#xff0c;J-Link调试器配合OpenOCD的组合能提供强大的硬件调试能力。不同于简单的包管理器安装&#xff0c;从源码编译OpenOCD可以确保获得最新功…...

OpenClaw自动化测试:Qwen3-32B驱动UI操作与结果校验

OpenClaw自动化测试&#xff1a;Qwen3-32B驱动UI操作与结果校验 1. 为什么选择OpenClaw做UI自动化测试 去年接手一个个人项目时&#xff0c;我遇到了一个典型痛点——每次代码更新后&#xff0c;都需要手动重复执行几十个UI操作步骤来验证核心功能。这种重复劳动不仅耗时&…...

【2026 最新】JDK 下载与安装:在 macOS 下使用 Homebrew 和 jenv 完美管理多版本 JDK

结合 Homebrew 和 jenv 是在 macOS 上管理多版本 JDK 的最佳实践。Homebrew 负责安装具体的 JDK 文件&#xff0c;而 jenv 负责在这些版本之间灵活切换。 Homebrew安装配置看下面的教程&#xff1a; 【2026 最新】Mac 终端神器 Homebrew 完全指南&#xff1a;从安装、换源加速…...

GIL移除后第一份生产级并发手册,深度解析subinterpreter隔离机制、跨上下文引用计数与零拷贝通信协议

第一章&#xff1a;Python无锁GIL环境下的并发模型概览Python 的全局解释器锁&#xff08;GIL&#xff09;长期被视为多线程 CPU 密集型任务的瓶颈。然而&#xff0c;随着 CPython 3.13 的正式引入“实验性无锁 GIL”&#xff08;--without-pymalloc 配合 --with-gildisabled 构…...

从理论到仿真:Simulink在无穷大电源与同步发电机三相短路分析中的实践

1. 电力系统短路分析的基础概念 第一次接触电力系统短路分析时&#xff0c;我也被各种专业术语搞得一头雾水。简单来说&#xff0c;短路分析就是研究电力系统在发生故障时的电流变化情况。想象一下家里的电路突然短路时&#xff0c;保险丝会"啪"的一声跳闸&#xff0…...

2026年,教培机构不可错过的在线教学平台大盘点

一、在线教育的崛起与挑战随着互联网技术的飞速发展&#xff0c;在线教育迎来了爆发式增长&#xff0c;成为教育领域的重要力量。据艾瑞咨询数据显示&#xff0c;中国在线教育行业市场规模已突破 6000 亿元&#xff0c;并呈现持续增长趋势。特别是在疫情期间&#xff0c;在线教…...

二极管工作原理与应用全解析

1. 二极管基础认知&#xff1a;电子世界的单向阀门我第一次接触二极管是在大学电子实验课上&#xff0c;当时看着这个小小的玻璃管状元件&#xff0c;很难想象它能在电路中起到如此关键的作用。直到亲眼目睹它只允许电流单向通过的特性&#xff0c;才真正理解为什么工程师们称它…...

避开这3个坑!用SPSS做描述性统计时90%新手会犯的错误(附正确操作截图)

避开这3个坑&#xff01;用SPSS做描述性统计时90%新手会犯的错误&#xff08;附正确操作截图&#xff09; 第一次打开SPSS时&#xff0c;那个布满英文按钮的界面就让我头皮发麻。记得研究生时期帮导师处理调研数据&#xff0c;我自信满满地导入了500份问卷&#xff0c;结果在组…...

【工业C# OPC UA配置黄金法则】:20年资深工程师亲授5大避坑指南与一键式配置模板

第一章&#xff1a;工业C# OPC UA配置黄金法则总览在工业自动化系统中&#xff0c;C# 与 OPC UA 的集成必须兼顾安全性、可维护性与实时性。配置不当不仅导致通信中断&#xff0c;更可能引发证书信任链失效、节点访问越权或会话超时风暴。以下核心原则构成稳定部署的基石。强制…...

读了50篇文献还是理不清脉络?百考通AI 5分钟生成有主线、有批判的文献综述

在高校学术写作中&#xff0c;文献综述是连接已有研究与创新探索的关键桥梁。它不仅体现作者对领域现状的掌握程度&#xff0c;更直接影响后续研究的深度与可行性。然而&#xff0c;对许多学生而言&#xff0c;撰写一篇专业、规范、有逻辑的综述常常令人望而却步——资料庞杂、…...