微服务框架 go-zero 快速实战
对于咱们快速了解和将 go-zero 使用起来,我们需要具备如下能力:
- 基本的环境安装和看文档的能力
- Golang 的基本知识
- Protobuf 的基本知识
- web,rpc 的基本知识
- 基本的 mysql 知识
其实这些能力,很基础,不需要多么深入,只需要你有所了解,这样至少对于咱们去看 go-zero 涉及的知识点就不会那么费劲儿
本文分为如下 4 个部分来分别介绍和快速实战微服务框架 go-zero
- 微服务框架 go-zero 的基本介绍
- go-zero 的环境搭建
- go-zero 的快速实战 rpc , api ,model 部分
微服务框架 go-zero 的基本介绍
go-zero 是一个集成了各种工程实践的 web 和 rpc 框架。通过弹性设计保障了大并发服务端的稳定性,经受了充分的实战检验。
go-zero 中的 api,rpc,数据库等涉及的代码,都可以给我们一键生成,无需耗费我们什么精力
只需要在生成的代码中填入自己的配置以及逻辑即可,咱们使用 go-zero 可以轻松做到如下效果:
- 轻松获得支撑千万日活服务的稳定性
- 内建级联超时控制、限流、自适应熔断、自适应降载等微服务治理能力,无需配置和额外代码
- 微服务治理中间件可无缝集成到其它现有框架使用
- 极简的 API 描述,一键生成各端代码
- 自动校验客户端请求参数合法性
- 大量微服务治理和并发工具包
对于咱们开发微服务可谓是极大的提高了开发效率和质量,减少了开发者的心智负担
go-zero 官方提供了一张架构图
从架构图我们知道,上述的各种效果离不开架构图中的每一个模块,本文先展示如下功能的应用:
- HTTP 协议
- gRPC 协议
- 日志记录
- 链路追踪
- 数据库
- ETCD 服务发现
- …
看到 go-zero 有这么多好处,架构图也非常清晰,是不是有点迫不及待了呢
go-zero 的环境搭建
不着急,工欲善其事必先利其器,咱们能将 go-zero 玩起来的先决条件是搭建基本的环境,为了接下来的实战做铺垫,咱们需要搭建如下几个工具
- 有一台基本的云服务器最好,虚拟机也没有问题
- 安装 etcd,mysql
- 安装 protoc 工具
- 安装 goctl 工具
安装 etcd,mysql
etcd
ETCD_VER=v3.5.0# choose either URL
GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GOOGLE_URL}rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-testcurl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz/tmp/etcd-download-test/etcd --version
/tmp/etcd-download-test/etcdctl version
/tmp/etcd-download-test/etcdutl version
安装完毕后,可以使用 etcdctl version 查看工具的版本
如果想了解 etcd 的基本使用,咱们不着急,本次文章使用不多,无需太过关注 etcd 的细节
mysql
Linux(centos) 下 Mysql 环境安装
安装 protoc 工具
go get -u github.com/golang/protobuf/protoc-gen-go@v1.3.2
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.14.0/protoc-3.14.0-linux-x86_64.zip
unzip protoc-3.14.0-linux-x86_64.zip
mv bin/protoc /usr/local/bin/
安装完毕后,可以使用 protoc --version 查看工具的版本
安装 goctl 工具
goctl
读作 go control
,不要读成 go C-T-L
。goctl
的意思是不要被代码控制,而是要去控制它。其中的 go
不是指 golang
安装咱们 golang 的时候,直接安装 go 1.16 版本以上的,然后执行如下命令即可
GOPROXY=https://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctl@latest
安装完毕后,可以使用 goctl --version 查看工具的版本
go-zero 的快速实战
环境安装完毕之后,我们就可以来进行实战了,刚才有说到 go-zero 是一个集成了各种工程实践的 web 和 rpc 框架,那么我们就可以来设计 web 部分的接口和 rpc 部分的接口
需求
- 例如有一个订单场景,我们需要查询某个租户的地址
- 另外在租户系统这边,需要添加租户
这个时候,我们知道,对于用户来说,访问的自然是 http 接口,那对于查询具体的租户信息,自然是内部微服务来进行处理
一般来说,HTTP 接口对外, RPC 接口对内
正如这样
先来定义 rpc 接口
- 咱们先建立项目目录:
mkdir my_test_demo/mymall -p
cd my_test_demo
go mod init my_test_demo
- 创建租户的 rpc 模块
mkdir mymall/tenant/rpc -p
cd mymall/tenant/rpc
- 编写 proto 文件
提供两个 rpc 接口
-
getTenant
- 获取租户信息
-
addTenant
- 添加租户
tenant.proto
syntax = "proto3";package tenant;option go_package = "./tenant";message TidReq {string name = 1;
}
message TenantRsp {// 租户名称string id = 1;// 租户名称string name = 2;// 用户地址string addr = 3;
}message addTenantReq {// 租户名称string name = 1;// 用户地址string addr = 2;
}message addTenantRsp {// 租户 idstring id = 1;
}service Tenant {rpc getTenant(TidReq) returns(TenantRsp);rpc addTenant(addTenantReq) returns(addTenantRsp);
}
- 使用 goctl 工具生成 golang 代码
goctl rpc protoc tenant.proto --go_out=./protoc --go-grpc_out=./protoc --zrpc_out=.
可以看到 goctl 工具给我们生成的代码目录是这样的
├── etc
│ └── tenant.yaml
├── internal
│ ├── config
│ │ └── config.go
│ ├── logic
│ │ ├── addtenantlogic.go
│ │ └── gettenantlogic.go
│ ├── server
│ │ └── tenantserver.go
│ └── svc
│ └── servicecontext.go
├── protoc
│ └── tenant
│ ├── tenant_grpc.pb.go
│ └── tenant.pb.go
├── tenant
│ └── tenant.go
├── tenant.go
└── tenant.proto
这个时候,关于 rpc 自动生成的部分就完成了
定义 api 接口
- 创建订单的 api 模块
回到项目根目录 my_test_demo
mkdir mymall/order/api -p
cd mymall/order/api
- 编写 api
定义一个 Get 方法,url 为 / api /order/get/:name 的 http 接口
order.api
type (OrderReq {Name string `path:"name"`}OrderReply {Id string `json:"id"`Name string `json:"name"`Addr string `json:"addr"`}
)
service order {@handler getOrderget /api/order/get/:name (OrderReq) returns (OrderReply)
}
- 使用 goctl 工具生成代码
goctl api go -api order.api -dir .
这个时候,我们可以看到,goctl 工具给我们生成的目录结构和代码是这个样子的
├── etc
│ └── order.yaml
├── internal
│ ├── config
│ │ └── config.go
│ ├── handler
│ │ ├── getorderhandler.go
│ │ └── routes.go
│ ├── logic
│ │ └── getorderlogic.go
│ ├── svc
│ │ └── servicecontext.go
│ └── types
│ └── types.go
├── order.api
└── order.go
同样的, web 部分自动生成的部分就完成了
数据库
- 创建 model 目录
回到项目根目录 my_test_demo
mkdir mymall/tenant/rpc/protoc/model -p
cd mymall/tenant/rpc/protoc/model
- 编写 sql
- 先在 linux 里面进入 mysql,创建一个数据库 test_demo
- 再创建一张表,表的字段如下面 sql 文件所述
tenant.sql
CREATE TABLE `tenant_info`
(`id` varchar(255) NOT NULL COMMENT 'tenant id',`name` varchar(255) NOT NULL COMMENT 'tenant name',`addr` varchar(255) NOT NULL COMMENT 'tenant addr',PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- 向 数据表中插入一条数据,为后续做准备
insert into tenant_info values("ceshiid", "约等于公司", "修罗道哦");
- 使用 goctl 工具生成 model 部分的代码
goctl model mysql ddl -src tenant.sql -dir .
可以看到 goctl 给我们生成的 model 代码是这个样子的
├── tenantinfomodel_gen.go
├── tenantinfomodel.go
├── tenant.sql
└── vars.go
填充逻辑层和配置
- Api 部分
- 修改 mymall/order/api/etc/order.yaml , 加上 etcd 的配置,咱们配置的 rpc 的 key 是 tenant.rpc
Name: order
Host: 0.0.0.0
Port: 9998
TenantRpc:Etcd:Hosts:- 127.0.0.1:2379Key: tenant.rpc
-
修改 ymall/order/api/internal/config/config.go ,Config struct 中加上 rpc 的配置
- TenantRpc zrpc.RpcClientConf
-
修改 mymall/order/api/internal/svc/servicecontext.go ,加上 rpc 的上下文
- TenantRpc tenant.Tenant
- TenantRpc:tenant.NewTenant(zrpc.MustNewClient(c.TenantRpc)),
- 修改 mymall/order/api/internal/logic/getorderlogic.go ,对逻辑层加上咱们自定义的逻辑,调用 rpc 的接口获取租户信息
func (l *GetOrderLogic) GetOrder(req *types.OrderReq) (resp *types.OrderReply, err error) {// todo: add your logic here and delete this line
rsp , err:=l.svcCtx.TenantRpc.GetTenant(l.ctx, &tenant.TidReq{Name: req.Name})if err != nil{return nil,err}return &types.OrderReply{Id: rsp.Id,Name: rsp.Name,Addr: rsp.Addr,},nil}
- 修改 mymall/order/api/internal/handler/getorderhandler.go ,去掉多导入的包
- Rpc 部分
- 修改 mymall/tenant/rpc/etc/tenant.yaml ,加上数据源和数据表的配置
Name: tenant.rpc
ListenOn: 127.0.0.1:8080
Etcd:Hosts:- 127.0.0.1:2379Key: tenant.rpcDataSource: root:123456@tcp(localhost:3306)/test_demo
Table: tenant_info
-
修改 mymall/tenant/rpc/internal/config/config.go
- DataSource string
- Table string
-
修改 mymall/tenant/rpc/internal/svc/servicecontext.go ,添加关于 mysql 的上下文
- Model model.TenantInfoModel
- Model:model.NewTenantInfoModel(sqlx.NewMysql(c.DataSource)),
-
修改 mymall/tenant/rpc/protoc/model/tenantinfomodel_gen.go ,新增一个数据库的方法 FindOneByName (这个是根据业务自身来选择是否要加)
- FindOneByName(ctx context.Context, name string) (*TenantInfo, error)
func (m *defaultTenantInfoModel) FindOneByName(ctx context.Context, name string) (*TenantInfo, error) {query := fmt.Sprintf("select %s from %s where `name` = ? limit 1", tenantInfoRows, m.table)var resp TenantInfoerr := m.conn.QueryRowCtx(ctx, &resp, query, name)switch err {case nil:return &resp, nilcase sqlc.ErrNotFound:return nil, ErrNotFounddefault:return nil, err}
}
- 修改 mymall/tenant/rpc/internal/logic/gettenantlogic.go 填充 GetTenant 的逻辑
效果验证
- 打开终端 1 操作 rpc
cd mymall/tenant/rpc
go mod tidy
go run tenant.go
- 打开终端 2 操作 api
cd mymall/order/api
go run order.go
- 打开终端 3 操作 curl
我们可以先使用 etcdctl 查看一下 tenant.rpc 是否存在
etcdctl get tenant.rpc --prefix
再使用 curl 来请求 api 的接口
curl -i "http://localhost:9998/api/order/get/约等于公司"
Api 的日志为
Rpc 的日志
通过上述日志我们知道,对于 api 的请求日志,mysql 的日志,rpc 的日志,咱们都能看到 trace 这个字段,实际上就是通过这个字段来进行链路跟踪的,细心的朋友就可以看到,从 api,到 rpc,到 mysql 这个 trace 字段的值都是同一个, 说明这是同一条调用链上的
其他的细节,咱们后续再聊
总结
至此,我们了解了 go-zero 微服务框架,快速实战了一个简单的 demo,这里我们实际可以体验到,关于 api,rpc ,或者是 model 层,绝大部分的代码都是 goctl 生成的,我们需要的就如下几件事
- 基本 api ,proto ,sql 的定义
- 修改 xml 配置 , 和 config.go 的配置
- 修改 svc 下面的关联上下线文
- 修改 logic 层,填上自己的逻辑
- 如果对于数据库生成默认的方法,不够满足业务场景,我们也可以依葫芦画瓢实现自己的方法,进行使用即可
另外,我们看到咱们定义的 proto 还有一个 addTenant 方法,实际上我们去实现的话,可以在 mymall/tenant 下添加 api 目录,按照上述 api 的添加方式来进行处理即可,感兴趣的朋友可以来尝试一波哦
如果想看源码的,欢迎访问地址:https://github.com/qingconglaixueit/my_test_Demo
感谢阅读,欢迎交流,点个赞,关注一波 再走吧
欢迎点赞,关注,收藏
朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是阿兵云原生,欢迎点赞关注收藏,下次见~
可以进入地址进行体验和学习:https://xxetb.xet.tech/s/3lucCI
相关文章:

微服务框架 go-zero 快速实战
对于咱们快速了解和将 go-zero 使用起来,我们需要具备如下能力: 基本的环境安装和看文档的能力 Golang 的基本知识 Protobuf 的基本知识 web,rpc 的基本知识 基本的 mysql 知识 其实这些能力,很基础,不需要多么深入&a…...
mysql基础面经之三:事务
6 事务 6.1 说一下事务的ACID和隔离级别 1 讲解了AID三个特性都是为了C(一致性)服务的。一般数据库需要使用事务保证数据库的一致性。 正确情况下最好详细讲讲: ACID是用来描述数据库事务的四个关键特性的首字母缩写,具体包括&a…...

JavaScript基本数组操作
在JavaScript中,内置了很多函数让我们可以去对数组进行操作,本文我们就来学习这些函数吧 添加元素 push ● push可以让我们在数组后面再添加一个数据,例如 const friends ["张三", "李四", "王五"]; frie…...

C#---第21: partial修饰类的特性及应用
0.知识背景 局部类型适用于以下情况: 类型特别大,不宜放在一个文件中实现。一个类型中的一部分代码为自动化工具生成的代码,不宜与我们自己编写的代码混合在一起。需要多人合作编写一个类 局部类型的限制: 局部类型只适用于类、接口、结构&am…...

SQL 语句继续学习之记录三
一,数据的插入(insert 语句的使用方法) 使用insert语句可以向表中插入数据(行)。原则上,insert语句每次执行一行数据的插入。 列名和值用逗号隔开,分别扩在()内,这种形式称为清单。…...

Nexus仓库介绍以及maven deploy配置
一 、Nexus仓库介绍 首先介绍一下Nexus的四个仓库的结构: maven-central 代理仓库,代理了maven的中央仓库:https://repo1.maven.org/maven2/; maven-public 仓库组,另外三个仓库都归属于这个组,所以我们的…...
A Survey on Knowledge-Enhanced Pre-trained Language Models
摘要 自然语言处理(NLP)已经通过使用BERT等预训练语言模型(plm)发生了革命性的变化。尽管几乎在每个NLP任务中都创造了新的记录,但plm仍然面临许多挑战,包括可解释性差,推理能力弱,以及在应用于下游任务时需要大量昂贵的注释数据。通过将外部知识集成到plm中,知识增强预训…...

SQL求解用户连续登录天数
数据分析面试过程中,一般都逃不掉对SQL的考察,可能是笔试的形式,也可能是面试过程中面试官当场提问,当场在纸上写出,或者简单说一下逻辑。 今天,就来分享一道面试中常常被问到的一类SQL问题:连…...

掌握逻辑漏洞复现技术,保护您的数字环境
环境准备 这篇文章旨在用于网络安全学习,请勿进行任何非法行为,否则后果自负。 1、支付逻辑漏洞 攻击相关介绍 介绍: 支付逻辑漏洞是指攻击者利用支付系统的漏洞,突破系统的限制,完成非法的支付操作。攻击者可以采…...

windows系统服务器在不解锁屏幕不输入密码的前提下,电脑通电开机启动程序。
在控制面板中找到“管理工具”中的 “任务计划程序”,打开“任务计划程序”窗口。如图: 双击打开任务计划程序,空白出右键创建基本任务,或者点击最右侧的创建基本任务。 输入名称,点击下一步。 先选择计算机启动时&a…...

spring cloud seata集成
目录 一、seata使用场景 二、seata组成 三、seata服务端搭建 四、客户端使用seata 4.1 客户端增加undo_log表 4.2 客户端增加seata相关配置 4.3 客户端使用注解 五、测试 一、seata使用场景 微服务中,一个业务涉及到多个微服务系统,每个微服务…...
HTTP 常⻅的状态码有哪些,以及适⽤场景
⼀、HTTP状态码 HT T P 状态码( HT T P S t a t u s Co d e )是⽤来表示⽹⻚服务器超⽂本传输协议响应状态的 3 位数字代 码。它由 RFC 2 6 1 6 规范定义,并得到 RFC 2 5 1 8 、 RFC 2 8 1 7 、 RFC 2 2 9 5 、 RFC 2 7 7 4 与 RFC 4 9 1 8…...
后端给前端传参数忽略空属性
JsonInclude JsonInclude注解用于指定在对象序列化为JSON字符串时,哪些属性应该被包含进去,哪些属性应该被忽略掉。 JsonInclude注解有以下几个常用选项: JsonInclude(JsonInclude.Include.NON_NULL):表示只有属性值不为null的属…...

SPSS教程:如何绘制带误差的折线图
SPSS教程:如何绘制带误差的折线图 1、问题与数据 研究者想研究45-65岁健康男性中,静坐时长和血胆固醇水平的关系,故招募100名研究对象询问其每天静坐时长(time),并检测其血液中胆固醇水平(cho…...
积分商城小程序如何精细化运营
随着移动互联网的发展,积分商城小程序成为了企业私域营销的重要组成部分。通过积分商城,企业可以激励用户参与、增加用户粘性,实现更好的用户互动和忠诚度提升。然而,要取得成功,积分商城小程序需要经过精细化的运营。…...
企业网络日志管理:EventLog Analyzer的卓越之处
企业网络日志管理对于维护网络安全、监控系统性能和合规性非常重要。随着网络规模和复杂性的增加,管理日志变得越来越具有挑战性。幸运的是,有一些优秀的工具可以帮助企业实现高效的日志管理。其中一款值得一提的工具是EventLog Analyzer。 一、EventLo…...
Python算法——滑动窗口问题
关于滑动窗口的概念,请自行到网上搜索相关资料,了解清楚再看本博客。 一、子组数最大平均数 LeetCode 第643题:https://leetcode.cn/problems/maximum-average-subarray-i/ 给你一个由 n 个元素组成的整数数组 nums 和一个整数 k 。 请你…...

使用 MATLAB 和 Simulink 对雷达系统进行建模和仿真
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
Linux 中的 sysctl 命令及示例
介绍 Linux管理员使用该命令在运行时sysctl读取或修改内核参数。无需重新启动即可实时控制和修改网络、 I/O 操作和内存管理设置的选项对于高可用性系统至关重要。 了解如何使用该sysctl命令及其选项来动态调整系统性能。...
Mybatis批量更新数据及其优化
需求场景:定时任务中,从其他平台同步数据,并更新当前平台数据库,表数据3W,分批更新某个字段,耗时巨大,约30min,尝试性能优化。 批量更新的几种常见方式: 1.foreach 循环…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...