go-zero超强工具goctl的常用命令api,rpc,model及其构建的服务解析
goctl api
详情移步:
go-zero的路由机制解析
基于go-zero的api服务刨析并对比与gin的区别
goctl rpc
goctl支持多种rpc,较为流行的是google开源的grpc,这里主要介绍goctl rpc protoc的代码生成与使用。
protoc是grpc的命令,作用是将proto buffer文件转化为相应语言的代码。这里gocrl集成了proto buffer。

--go_out和--go-grpc_out分别是生成的pb文件和_grpc.pb文件的目录。
使用protoc命令的前提条件是要有proto文件,如下:
syntax = "proto3";package pb;option go_package = "./pb";//获取某用户的认证详细信息
message IdentifyDetailReq{string Id = 1;
}message Detail{string Id = 1; //客户idstring Contacts = 2; //企业联系人string Corporation = 3; //企业联系人身份证号int64 Status = 4; //认证状态 0-待审核;1-已通过;2-未通过string CompanyName = 5; //企业名称string Phone = 6; //企业联系人电话string Address = 7; //通讯录地址string Reason = 8; //认证不通过理由int64 Type = 9; //企业证件类型 0-营业执照三证合一;1-营业执照非三证合一;2-非营业执照string qualifications = 10;//企业资质信息
}
message IdentifyDetailResp{Detail IdentifyInfo = 1;
}service Identify{rpc IdentifyDetail(IdentifyDetailReq) returns (IdentifyDetailResp);
}
初始项目目录如下:

执行命令:
goctl rpc protoc test.proto --go_out=./pb --go-grpc_out=./pb --zrpc_out=.

生成目录文件

grpc最主要的文件是pb文件,rpc远程调用都基于这两个文件。
goctl rpc 生成的go文件和grpc不并不一样,zero对grpc进一步分装,且封装的库放在github.com/zeromicro/go-zero/zrpc中。
原生grpc
和原生grpc使用不同的是:
-
开发者自定义
UnimplementedXXXServer的实现类 -
重写指向
UnimplementedXXXServer实现类的所有方法。 -
编写服务端代码并注册所有实现的方法
-
客户端调用方法。
在proto文件生成的_grpc.pb文件自定义的接口:

需要新建该类的实现类并重写所有方法,完成特定功能。由于返回值参数都是在pb文件中,具备任何两个pb文件的够可以构建该同名称函数的rpc远程调用,并返回参数后序列化。
另外还需的注意的是grpc只生成的pb文件客户端与服务端都需要开发者来编写。
gRPC远程调用服务端与客户端连接详解
zero的grpc
在go-zero对grpc进一步封装,并将封装的,完成pb文件的生成与服务端的代码生成。如下自动生成的目录:

grpc原生命令只生成两个pb文件。
goctl rpc proto生成4个目录和一个rpc服务端启动程序。其中第二个目录是对grpc客户端代码的进一步封装,自定义的客户端。
在使用goctl rpc proto生成的代码是可以快速的构建rpc应用,方便的使用rpc客户端,另外zero还对etcd进行了集成,无需开发者操作,任然可以使用goctl一键生成。
pb文件就不再赘述了,这是看grpc使用的第二步,实现接口方法并注册方法,方法的实现zero也是使用服务层与逻辑层的调用方式,如下:
- server目录实现了
_grpc.pb的所有方法,但是在方法中并没有写具体实现,而是直接调用了logic层。

- logic层具体实现

此次封装只是隐藏了一个入参,当然也可以直接使用logic实现完整的代码,直接在服务点调用,跳过server也是可以的。
唠叨grpc第三步,服务端代码编写与接口注册,这一步也是由goctl生成的。在grpc中一般是调用_grpc.pb中的RegisterXXXServer方法参数为一个初始化的grpc服务端,可以接口。

第一个参数来自grpc目录(zero集成了grpc),第二个参数也在_grpc.pb为包含自定义方法的接口。

在go-zero中也是直接实现了服务端编写,查看源码都可以发现实现服务端构建都是使用了zrpc.MustNewServer方法,源码如下:
// A RpcServer is a rpc server.
type RpcServer struct {server internal.Serverregister internal.RegisterFn
}// MustNewServer returns a RpcSever, exits on any error.
func MustNewServer(c RpcServerConf, register internal.RegisterFn) *RpcServer {server, err := NewServer(c, register)logx.Must(err)return server
}
该方法传入了RpcServerConf服务端配置,肯定是必须的,要设置ip监听端口等;第二个参数呢是一个是一个参数为grpc.Server的函数,显然安装常规的构建服务端方法,就差一个接口了。

那么主要在这个方法内部调用pb的注册方法就可以了,看到zero的代码

调用了_grpc.pb方法注册,但不同的是第二个参数,并不是_grpc.pb的接口,而是server目录的封装的方法。
注册方法的参数是两个接口,可以是任意类型,但是第一个参数必须是grpc.Server
这里zero有一次并没有传入接口,而是自定义的结构体,结构体的方法被注册到grpc服务端。

pb.UnimplementedIdentifyServer构建grpc服务端的关键,重写了其方法,将其子类通过注册的方式注册到grpc服务端。
以上就zero对grpc的封装过程,goctl直接实现了构建grpc服务的前三个步骤,开发者只需要编写实现逻辑和少量配置即可。也就是说通过goctl生成的rpc服务只需要两个简单的步骤:
- 在yaml配置文件配置
zrpc.RpcServerConf所需要的参数

2. logic层编写方法实现的具体逻辑

以上就是go-zero rpc服务端了。
其实客户端goctl也生成了,对于原生的grpc创建实现客户端包含连个步骤:1. 配置客户端连接参数;2. 实例化客户端对象。
源码也在_grpc.pb文件中:

图片上的转换过程有点复杂,出现了不少接口与接口的变化,不太好懂,当下只知道如何使用即可。
//配置连连接参数(无加密)
dial, err := grpc.Dial("localhost:1099", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {println("failed grpc connect", err)
}
defer dial.Close()
//创建客户端连接
client := protoInterface.NewInterfaceClient(dial)
//通过客户端调用方法
res, err := client.GetProduct(context.Background(), &protoInterface.Request{ParamString: "hello",
})
在上述代码中最核心的就是grpc.Dial这步,创建grpc连接,后续调用pb的NewXXXClient传入该参数就得到了一个客户端对象就可以调用方法了。
go-zero客户端
zero中进一步封装,看zero源码(一般是生成文件的第二个目录即在etc下面的目录文件是对客户端的封装)。

第一个表示接口方法就是pb客户端的方法,第二个是对客户端的封装,第三个是创建客户端方法,第四个是方法实现,其实这都可上一小结原生pb的grpc客户端一模一样,就是换了个名字。
那么显然不能再用gprc原生的内容了,使用这些包装的rpc客户端也很简单,显然NewIdentify是构建客户端实例的方法,就差连接对象了。查看zrpc.Client源码如下:

再查看internal.Client源码:

巧了吗这不是,到头来还是自己,却有三个名。

到此思路就清晰了。
实例化一个zrpc.Client或者直接使用grpc.Dial,需要注意的是zrpc.Client类型和同款类型是一个接口啊,没法像接口那样直接实例化,需要通过另一个方法实例化。
直接在zrpc库中找即可

官方推荐
conn := zrpc.MustNewClient(zrpc.RpcClientConf{Target: "dns:///127.0.0.1:8080",
})
zrpc.MustNewClient方法可以实例化,其参数是一个zrpc.RpcClientConf结构体。这个参数可以配置在config目录下额文件中,通过配置获取。
到此也可以明白这莫多层的封装的意义了把,就是把下面这些配置集成了grpc中,并能通过yaml文件配置。
客户端对象实例获取后,如何可以直接调用方法获取服务端返回的数据库,保证服务端启动者即可。

etcd的整合
上述过程还未使用etcd的服务注册与发现功能,可以看到上之前的一些配置类中如服务端zrpc.RpcServerConf与zrpc.RpcClientConf均出现了Etcd的配置类,在go-zero中使用etcd也是十分方便。一般有如下几个步骤:
- 安装etcd,确保其正常运行
- rpc服务端构建etcd心跳客户端持续发送心跳,并上传数据
- rpc客户端构建etcd普通客户端获取数据。
go-zero中使用etcd和单独使用区别不大,主要是配置文件那块。
详情请移步go-zero微服务实战——etcd服务注册与发现
goctl model
goctl model支持多种数据库,较为常用的是mysql,这里主要介绍goctl mode mysql的代码生成与使用。

参考
goctl model mysql datasource -url="user:password@tcp(127.0.0.1:3306)/database" -table="table1,table2" -dir="./model"
运行命令后会在指定的目录下生成三个文件

其中usermodel.go是用户自定义的DML,DQL,开发者可在此处定义自己编写的sql查询语句;usermodel_gen.go是goctl自动生成的DML,DQL实现了数据库的基本操作即CRUD操作;第三个var.go就是自定义的数据库操作失败的返回值和其他参数。
goclt自动生成数据库引擎,在
goctl model mysql命令的datasource参数就是配置数据库引擎的参数。接下来会参数如何使用。
可以看到user_mode_gen.go的userModel接口定义了很多方法:

而这些接口最终都指向了defaultUserModel

转到defaultUserModel的定义
defaultUserModel struct {sqlc.CachedConntable string
}
结构体定义了缓存和表名,后者由命令参数传递。
同源文件下也提供了实例化的方法:
func newUserModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) *defaultUserModel {return &defaultUserModel{CachedConn: sqlc.NewConn(conn, c, opts...),table: "`user`",}
}
通过该方法创建一个defaultUserModel的实例,那么通过该方法创建实例,就可以调用接口的所有方法了。但是可以看到这个方法是私有的。

在xxxmodel.go文件下也有一个NewUserModel方法是公开的,如下:
// NewUserModel returns a model for the database table.
func NewUserModel(conn sqlx.SqlConn) UserModel {return &customUserModel{defaultUserModel: newUserModel(conn),}
}
该方法对defaultUserModel进行了多次封装会有返回以newUserModel构建的defaultUserModel。开发者可以使用 NewUserModel来调用model生成的方法。

在对defaultUserModel多次封装的过程中出现了如下的接口和结构体:

UserModel接口内嵌userModel显然是其子接口,继承了userModel的方法且是公开的。customeUserModel也是defaultUserModel子类,并只能通过NewUserModel方法调用。显然该层继承是为了方便开发者拓展model层,实现自定义sql操作数据库。
自定义model的一般步骤包括:1. xxxmodel的接口中定义方法;2. 在同包下实现方法,并指向defaultUserModel的实现类。

如下使用NewUserModel就可以直接调用自定义的方法了

自定义方法操作数据库
除了上述使用goctl的model规范操作数据库外,也可以通过自定义的方法操作数据库。会看model的的代码,其中操作数据库的核心就是sqlx.SqlConn
这里的sqlx来源与zero的库
"github.com/zeromicro/go-zero/core/stores/sqlx"
在sqlx中有一个NewMysql方法返回sqlx.SqlConn实例,就可以直接通过该方法返回的对象直接操作数据库。
var mysql = sqlx.NewMysql(datasource)
func Test2(t *testing.T) {mysql := sqlx.NewMysql("username:password@tcp(ip:3306)/databasename?charset=utf8mb4&parseTime=True")sql_ := "select * from user"user := User{}mysql.QueryRowCtx(context.Background(), &user, sql_)fmt.Println(user)
}
直接调用sqlx.SqlConn实例操作数据库的方法即可。
整合第三方框架
也可以整合一些第三方框架如gorm,xorm等,这就比较简单了,go get [address]安装。1. 封装工具类,暴露数据库引擎实例;2. 通过实例方法操作数据库。
可gin,iris,beego等框架整合xorm一样的方式,就不再过多叙述。
相关文章:
go-zero超强工具goctl的常用命令api,rpc,model及其构建的服务解析
goctl api 详情移步: go-zero的路由机制解析 基于go-zero的api服务刨析并对比与gin的区别 goctl rpc goctl支持多种rpc,较为流行的是google开源的grpc,这里主要介绍goctl rpc protoc的代码生成与使用。 protoc是grpc的命令,作用…...
手机python编程软件怎么用,手机python编程软件下载
大家好,小编来为大家解答以下问题,手机python编程软件保存的代码在哪里,手机python编程软件怎么运行,现在让我们一起来看看吧! 原标题:盘点几个在手机上可以用来学习编程的软件 前天在悟空问答的时候&#…...
【使用 DSP 滤波器加速速度和位移】使用信号处理算法过滤加速度数据并将其转换为速度和位移研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
家居行业解决方案 | 君子签电子签约助力家居企业减负增效
过去,家居行业因供需两端碎片化、服务链条较长等因素,导致线上发展较为缓慢,近年来,互联网的发展推动直播电商、兴趣电商兴起,促使家居行业数字化建设需求越来越为迫切。 合同管理作为家居行业企业经营的一项重要管理…...
Nodejs 第五章(Npm run 原理)
npm run xxx 发生了什么 按照下面的例子npm run dev 举例过程中发生了什么 读取package json 的scripts 对应的脚本命令(dev:vite),vite是个可执行脚本,他的查找规则是: 先从当前项目的node_modules/.bin去查找可执行命令vite如果没找到就去全局的node…...
150. 逆波兰表达式求值
给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意: 有效的算符为 、-、* 和 / 。 每个操作数(运算对象)都可以是一个整数或者另一个表达式。 两个…...
js中的设计模式
设计模式 代码整体的结构会更加清楚,管理起来会更加方便,更好地维护 设计模式是一种思想 发布订阅 模块化开发 导入很多模块 容器即数组存储未来要执行的方法,同addEventListener 数组塌陷问题* 由于删除了元素,导致从删除元素的位…...
PostgreSQL:string_agg 多列值聚合成一列
PostgreSQL:string_agg 多列值聚合成一列 string_agg是PostgreSQL中的一个聚合函数,用于将一组值连接为一个字符串。它接受两个参数:要连接的值和连接符。 语法如下: string_agg(expression, delimiter)其中,expression是要连接…...
通向架构师的道路之apache_tomcat_https应用
一、总结前一天的学习 通过上一章我们知道、了解并掌握了Web Server结合App Server是怎么样的一种架构,并且亲手通过Apache的Http Server与Tomcat6进行了整合的实验。 这样的架构的好处在于: 减轻App Server端的压力,用Web Server来分压…...
iOS——锁与死锁问题
iOS中的锁 什么是锁锁的分类互斥锁1. synchronized2. NSLock3. pthread 递归锁1. NSRecursiveLock2. pthread 信号量Semaphore1. dispatch_semaphore_t2. pthread 条件锁1. NSCodition2. NSCoditionLock3. POSIX Conditions 分布式锁NSDistributedLock 读写锁1. dispatch_barri…...
恒运资本:股票总市值是什么意思?
职业新手可能会疑惑地问,股票总市值到底是什么意思?究竟,这是普通出资者常常看到的词汇,要了解股票总市值的含义,是需求了解金融商场的基本概念的。 股票总市值简介 股票的总市值是由公司一切的股票的数量乘以现在的价…...
Selenium Chrome Webdriver 如何获取 Youtube 悬停文本
导语 Youtube 是一个非常流行的视频分享平台,有时候我们可能想要爬取一些视频的信息,比如标题、播放量、点赞数等。但是有些信息并不是直接显示在网页上的,而是需要我们将鼠标悬停在某个元素上才能看到,比如视频的时长、上传时间…...
【LeetCode每日一题】——766.托普利茨矩阵
文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【题目进阶】八【解题思路】九【时间频度】十【代码实现】十一【提交结果】 一【题目类别】 矩阵 二【题目难度】 简单 三【题目编号】 766.托普利茨矩阵 四【题目描述…...
第三方材料检测实验室LIMS系统源码 lims源码
实验室LIMS系统采用国际规范的业务管理流程和严格的质量控制体系,对每个检测流程节点采用 “人、机、料、法、环、测”进行质量控制,可记录,可追溯。强大的数据查询和统计分析能力,提高工作效率;自动化地采集实验室原始…...
【数据结构与算法——TypeScript】数组、栈、队列、链表
【数据结构与算法——TypeScript】 算法(Algorithm)的认识 解决问题的过程中,不仅仅 数据的存储方式会影响效率,算法的优劣也会影响效率 什么是算法? 定义: 🟢 一个有限指令集,每条指令的描述不依赖于言语…...
[运维|中间件] Apache APISIX使用笔记
简介 Apache APISIX 是一个现代化、高性能、可扩展的开源 API 网关和微服务管理平台。 安装 快速安装 curl -sL https://run.api7.ai/apisix/quickstart | sh...
Android Intent 使用(详细版)
经典好文推荐,通过阅读本文,您将收获以下知识点: 一、通过组件名启动 二、通过包名、类名启动 三、通过类启动 四、打电话 五、发短信 六、打开网页 七、播放音乐 八、打开图片 九、创建闹钟 十、创建定时器 十一、添加日历事件 十二、拍照 十三、打开Camera 十四、打开视频录…...
【Clion 2】多行TODO使用
一、TODO: 说明: 有时需要标记部分代码以供将来参考: 优化和改进的领域、可能的更改、要讨论的问题等等。 支持: TODO和FIXME小写和大写。这些模式可以在任何受支持的文件类型的行注释和块注释内使用。 创建TODO项 在要添加注释的代码行中…...
【运维】hive 终端突然不能使用:Hive Schema version does not match metastore‘s schema version
文章目录 一. 问题描述二. 常规排查1. 元数据库2. hive-site.xml相关meta连接信息检查 三. 正解 一. 问题描述 进入hive终端,执行如下命令报错: hive> show tables; FAILED: SemanticException org.apache.hadoop.hive.ql.metadata.HiveException: …...
P1049 [NOIP2001 普及组] 装箱问题
题目描述 有一个箱子容量为 V,同时有 n 个物品,每个物品有一个体积。 现在从 n 个物品中,任取若干个装入箱内(也可以不取),使箱子的剩余空间最小。输出这个最小值。 输入格式 第一行共一个整数 V&#…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...

