RPC-thrift实践
参考:https://www.cnblogs.com/52fhy/p/11146047.html
参考:https://juejin.cn/post/7138032523648598030
实践
- 安装thrift
- brew install thrift
- thrift -version
- 编写thrift文件
- 新建文件夹thrift
- 新建文件
- 结构体文件
- Struct.thrift
- 服务文件
- Service.thrift
- 结构体文件
namespace go TestThriftstruct MyStructReq {1:required string reqMessage;
}struct MyStructResp {1:required string respMessage;
}
include "Struct.thrift"namespace go TestThriftservice MyService {Struct.MyStructResp MyQuery(1:required Struct.MyStructReq req)
}
- 生成idl文件
- Interface Definition Language
thrift -r --gen go XXX.thrift
- 编写服务程序(go)
cd testmkdir thrift_go_servicego mod init thrift_go_service- 生成idl文件,代码中需要依赖这个
thrift -r --gen go ~/PycharmProjects/thrift/Service.thrift
- 编写代码
package mainimport ("context""fmt""github.com/apache/thrift/lib/go/thrift""net""os""strconv""thrift_go_service/gen-go/TestThrift"
)type MyHandler struct {
}func (my *MyHandler) MyQuery(ctx context.Context, req *TestThrift.MyStructReq) (resp *TestThrift.MyStructResp, err error) {resp = &TestThrift.MyStructResp{}s := map[string]string{"hhh": "nihao","what": "why",}if v, ok := s[req.ReqMessage]; ok {resp.RespMessage = vreturn}resp.RespMessage = strconv.Itoa(len(req.ReqMessage))return
}func main() {transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory())protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()serverTransport, err := thrift.NewTServerSocket(net.JoinHostPort("localhost", "9001"))if err != nil {fmt.Println("err:", err)os.Exit(1)}handler := &MyHandler{}processor := TestThrift.NewMyServiceProcessor(handler)server := thrift.NewTSimpleServer4(processor, serverTransport, transportFactory, protocolFactory)err = server.Serve()if err != nil {fmt.Println("err:", err)}
}
- 编写客户端的代码
mkdir thrift_go_clientgo mod init thrift_go_client- 生成idl文件,代码中需要依赖这个
thrift -r --gen go ~/PycharmProjects/thrift/Service.thrift
- 编写代码
package mainimport ("context""fmt""github.com/apache/thrift/lib/go/thrift""net""os""thrift_go_client/gen-go/TestThrift"
)func main() {tSocket, err := thrift.NewTSocket(net.JoinHostPort("localhost", "9001"))if err != nil {fmt.Println("err:", err)os.Exit(1)}transportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory())transport, _ := transportFactory.GetTransport(tSocket)protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()client := TestThrift.NewMyServiceClientFactory(transport, protocolFactory)defer transport.Close()if err := transport.Open(); err != nil {fmt.Println("err:", err)os.Exit(1)}ctx := context.Background()d, err := client.MyQuery(ctx, &TestThrift.MyStructReq{ReqMessage: "hhh"})fmt.Println(d)
}
问题
go版本问题
启动service服务时候
✘ XXX@XXX ~/XXX/GoProjects/thrift_go_service go run main.go
# github.com/apache/thrift/lib/go/thrift
../../../go/pkg/mod/github.com/apache/thrift@v0.17.0/lib/go/thrift/deserializer.go:83:12: syntax error: unexpected [, expecting semicolon or newline or }
../../../go/pkg/mod/github.com/apache/thrift@v0.17.0/lib/go/thrift/pointerize.go:24:13: syntax error: unexpected [, expecting (
../../../go/pkg/mod/github.com/apache/thrift@v0.17.0/lib/go/thrift/pool.go:28:13: syntax error: unexpected any, expecting ]
../../../go/pkg/mod/github.com/apache/thrift@v0.17.0/lib/go/thrift/pool.go:30:16: syntax error: unexpected newline, expecting name or (
../../../go/pkg/mod/github.com/apache/thrift@v0.17.0/lib/go/thrift/pool.go:31:1: syntax error: non-declaration statement outside function body
../../../go/pkg/mod/github.com/apache/thrift@v0.17.0/lib/go/thrift/pool.go:38:13: syntax error: unexpected [, expecting (
../../../go/pkg/mod/github.com/apache/thrift@v0.17.0/lib/go/thrift/pool.go:38:37: method has no receiver
../../../go/pkg/mod/github.com/apache/thrift@v0.17.0/lib/go/thrift/pool.go:40:21: method has no receiver
../../../go/pkg/mod/github.com/apache/thrift@v0.17.0/lib/go/thrift/pool.go:40:21: syntax error: unexpected *, expecting name or (
../../../go/pkg/mod/github.com/apache/thrift@v0.17.0/lib/go/thrift/pool.go:46:16: method has no receiver
../../../go/pkg/mod/github.com/apache/thrift@v0.17.0/lib/go/thrift/pool.go:46:16: too many errors
note: module requires Go 1.18
- 提示需要升级go版本
- brew install go@1.18
- 切换版本:
- 参考:https://learnku.com/go/wikis/61549
- brew unlink go
- brew link go@1.18
- go version
ide的thrift文件打开方式
- ide中可以配置thrift插件
- 参考:https://blog.csdn.net/x369201170/article/details/51604284
- ide中修改.thrift文件的打开方式
- 参考:https://blog.csdn.net/qq_25046261/article/details/81666118
- 安装了thrift插件之后,可以找到对应的默认打开方式
- thrift的执行文件地址:
which thrift
- thrift的执行文件地址:
- 查看thrift的执行目录
- 参考:https://www.cnblogs.com/MakeView660/p/11398492.html
*which thrift
- 参考:https://www.cnblogs.com/MakeView660/p/11398492.html
如果服务端和客户端依赖的idl文件不一样,能行吗
- 可行
- 只要结构体名、函数名一致
- 这种情况出现在idl接口文件升级的时候
相关文章:
RPC-thrift实践
参考:https://www.cnblogs.com/52fhy/p/11146047.html 参考:https://juejin.cn/post/7138032523648598030 实践 安装thrift brew install thriftthrift -version 编写thrift文件 新建文件夹thrift新建文件 结构体文件 Struct.thrift 服务文件 Service.…...
Maven:工程的拆分与聚合
Maven 拆分与聚合创建父工程创建子模块pom.xml配置示例拆分与聚合 在 Maven 中, 拆分是将一个完整的项目分成一个个独立的小模块,聚合是将各个模块进一步组合,形成一个完整的项目。接下来简单示例拆分与聚合的过程。 创建父工程 父工程,一个pom工程,目录结构简单,只需有…...
使用uniapp创建小程序和H5界面
uniapp的介绍可以看官网,接下来我们使用uniapp创建小程序和H5界面,其他小程序也是可以的,只演示创建这2个,其实都是一套代码,只是生成的方式不一样而已。 uni-app官网 1.打开HBuilder X 选择如图所示,下…...
密度峰值聚类算法(DPC)
密度峰值聚类算法目录DPC算法1.1 DPC算法的两个假设1.2 DPC算法的两个重要概念1.3 DPC算法的执行步骤1.4 DPC算法的优缺点matlab代码密度计算函数计算delta寻找聚类中心点聚类算法目录 DPC算法 1.1 DPC算法的两个假设 1)类簇中心被类簇中其他密度较低的数据点包围…...
RabbitMQ相关问题
文章目录避免重复消费(保证消息幂等性)消息积压上线更多的消费者,进行正常消费惰性队列消息缓存延时队列RabbitMQ如何保证消息的有序性?RabbitMQ消息的可靠性、延时队列如何实现数据库与缓存数据一致?开启消费者多线程消费避免重复消费(保证消…...
操作系统 三(存储管理)
一、 存储系统的“金字塔”层次结构设计原理:cpu自身运算速度很快。内存、外存的访问速度受到限制各层次存储器的特点:1)主存储器(主存/内存/可执行存储器)保存进程运行时的程序和数据,内存的访问速度远低于…...
day34 贪心算法 | 860、柠檬水找零 406、根据身高重建队列 452、用最少数量的箭引爆气球
题目 860、柠檬水找零 在柠檬水摊上,每一杯柠檬水的售价为 5 美元。 顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。 每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个…...
使用canvas给上传的整张图片添加平铺的水印
写在开头 哈喽,各位倔友们又见面了,本章我们继续来分享一个实用小技巧,给图片加水印功能,水印功能的目的是为了保护网站或作者版权,防止内容被别人利用或白嫖。 但是网络中,是没有绝对安全的,…...
[安装之4] 联想ThinkPad 加装固态硬盘教程
方案:保留原有的机械硬盘,再加装一个固态硬盘作为系统盘。由于X250没有光驱,这样就无法使用第二个2.5寸的硬盘。还好,X250留有一个M.2接口,这样,就可以使用NGFF M.2接口的固态硬盘。不过,这种接…...
Java数据类型、基本与引用数据类型区别、装箱与拆箱、a=a+b与a+=b区别
文章目录1.Java有哪些数据类型2.Java中引用数据类型有哪些,它们与基本数据类型有什么区别?3.Java中的自动装箱与拆箱4.为什么要有包装类型?5.aab与ab有什么区别吗?1.Java有哪些数据类型 8种基本数据类型: 6种数字类型(4个整数型…...
GoLang设置gofmt和goimports自动格式化
目录 设置gofmt gofmt介绍 配置gofmt 设置goimports goimports介绍 配置goimports 设置gofmt gofmt介绍 Go语言的开发团队制定了统一的官方代码风格,并且推出了 gofmt 工具(gofmt 或 go fmt)来帮助开发者格式化他们的代码到统一的风格…...
【k8s】如何搭建搭建k8s服务器集群(Kubernetes)
搭建k8s服务器集群 服务器搭建环境随手记 文章目录搭建k8s服务器集群前言:一、前期准备(所有节点)1.1所有节点,关闭防火墙规则,关闭selinux,关闭swap交换,打通所有服务器网络,进行p…...
DIDL4_前向传播与反向传播(模型参数的更新)
前向传播与反向传播前向传播与反向传播的作用前向传播及公式前向传播范例反向传播及公式反向传播范例小结前向传播计算图前向传播与反向传播的作用 在训练神经网络时,前向传播和反向传播相互依赖。 对于前向传播,我们沿着依赖的方向遍历计算图并计算其路…...
链表学习之链表划分
链表解题技巧 额外的数据结构(哈希表);快慢指针;虚拟头节点; 链表划分 将单向链表值划分为左边小、中间相等、右边大的形式。中间值为pivot划分值。 要求:调整之后节点的相对次序不变,时间复…...
(考研湖科大教书匠计算机网络)第五章传输层-第一、二节:传输层概述及端口号、复用分用等概念
获取pdf:密码7281专栏目录首页:【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一:传输层概述(1)概述(2)从计算机网络体系结构角度看传输层(3)传输层意义二&am…...
C#:Krypton控件使用方法详解(第七讲) ——kryptonHeader
今天介绍的Krypton控件中的kryptonHeader,下面开始介绍这个控件的属性:控件的样子如上图所示,从上面控件外观来看,这个控件有三部分组成。第一部分是前面的图片,第二部分是kryptonHeader1文本,第三部分是控…...
5年软件测试工程师分享的自动化测试经验,一定要看
今天给大家分享一个华为的软件测试工程师分享的关于自动化测试的经验及干货。真的后悔太晚找他要了, 纯干货。一定要看完! 1.什么是自动化测试? 用程序测试程序,用代码取代思考,用脚本运行取代手工测试。自动化测试涵…...
什么是猜疑心理?小猫测试网科普小作文
什么是猜疑心理?猜疑心理是说一个人心中想法偏离了客观事实,牵强附会,往往是指不好的一面,对别人的一言一行都充满了不良的解读,认为这些对自己都有针对性,目的性,对自己都是不利的。猜疑心理重…...
Redis命令行对常用数据结构String、list、set、zset、hash等增删改查操作
1.Redis命令的小套路 - NX:not exist - EX:expire - M:multi 2.基本操作 ①切换数据库 Redis默认有16个数据库。 115 # Set the number of databases. The default database is DB 0, you can select 116 # a different one on a per-con…...
mycobot 使用教程
(1) 树莓派4B ubuntu系统调整swap空间与使SD卡快速扩容参考:https://www.bilibili.com/read/cv14825069https://blog.csdn.net/weixin_45824920/article/details/114381292?spm1001.2101.3001.6650.1&utm_mediumdistribute.pc_relevant.none-task-blog-2%7Edef…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
