go-zero最佳实践
.
├── Dockerfile -- docker构建文件
├── Jenkinsfile -- jenkins流水线脚本
├── LICENSE -- MIT许可证
├── Makefile
├── README.md -- 文档
├── __test__ -- 测试单元
├── constants -- 常量
│ ├── errors -- 错误定义
│ └── types -- 枚举类型定义
├── deployment -- 部署文件夹
├── docker-compose.yml
├── example -- 示例代码
├── go.mod -- golang依赖包
├── helper -- 工具类
│ ├── area.go -- 中国省市区解析器
│ ├── area_test.go -- 单元测试
│ ├── breaker -- 限流器
│ ├── cmd.go -- 命令行执行器
│ ├── contextx -- 上下文
│ ├── converter.go -- 类型转换器
│ ├── division.go -- sqlite的区域
│ ├── division_test.go -- 单测
│ ├── divisions.sqlite -- 地区文件sqlite
│ ├── email -- 邮件工具类
│ ├── ffmpeg.go -- FFmpeg执行
│ ├── ffmpeg_test.go -- 单测
│ ├── logrusx.go -- 日志中间件
│ ├── obs -- 华为对象存储
│ ├── pprof.go -- pprof工具
│ ├── pprof_test.go -- 单测
│ ├── rabbitmq -- 消息队列(rabbitmq)
│ ├── redis.go -- redis中间件
│ ├── redis_model.go -- 模型定义
│ ├── redis_test.go -- 单测
│ ├── sqlx -- 数据库工具类
│ ├── swagger.go -- swagger工具
│ ├── tracex -- 链路追踪工具
│ ├── validate.go -- validate工具
│ └── validate_test.go -- 单测
├── middlewares -- 中间件
│ └── log_trace.go -- 日志中间件
├── model -- 数据库模型
│ ├── mongo -- MongoDB模型
│ └── mysql -- MYSQL模型
├── my_zero -- zero模块
│ ├── Dockerfile -- 构建文件
│ ├── README.md -- 文档
│ ├── api -- api文件夹
│ ├── etc -- 配置文件
│ ├── internal -- 内部逻辑
│ ├── my-zero.go -- 入口函数
│ └── my_zero.api -- 入口api文件
├── order -- 订单模块
│ └── api -- api文件夹
├── scripts -- 脚本
│ ├── k8s_deploy.sh -- 部署脚本
├── static -- 静态文件
├── task -- 任务模块
│ ├── Dockerfile -- 构建文件
│ ├── README.md -- 文档
│ ├── api -- api文件夹
│ ├── etc -- 配置文件
│ ├── internal -- 内部逻辑
│ ├── swagger.json -- swagger文件
│ ├── task-k8s.yaml -- 部署文件
│ ├── task.api -- 入口api
│ ├── task.go -- 入口函数
│ └── task.sh -- 脚本
├── template -- goctl模板
│ └── mongo -- mongo模板
├── user -- 用户模块
│ └── rpc -- rpc模块
- exec
goctl api new my_zero
,then you will see a new service named my-zero.
-
if
protoc,protoc-gen-go,protoc-gen-rpc-go
are not installed, try withgoctl env check -i -f
; -
write a *.proto eg:user.proto
-
exec
cd ./user/rpc && goctl rpc protoc user.proto --go_out=./types --go-grpc_out=./types --zrpc_out=.
-
do your business in getUserLogic.go
- cd into target file && exec
goctl api go -api my_zero.api -style goZero -dir .
- cd into target file && exec
goctl docker -go my-zero.go
-
migrate:gorm migrate
-
auto gen db DDL through models;
-
you cannot drop a index with migrate;
-
it's convenient to code in some special columns.
-
-
autogen model: go-gorm gen
-
autogen model:connect to DB,and use DDL to gen model CURD && model columns;
-
you don't need care index in dbs;
-
it's convenient to sync model in code through db.
-
-
choose the most suitable is necessary.
-
根据api文件生成接口:
goctl api go -api task.api -style go_zero -dir .
,驼峰命名的话go_zero
替换成goZero
-
根据api文件生成swagger:
goctl api plugin -plugin goctl-swagger="swagger -filename swagger.json" -api task.api
-
Dockerfile生成:
goctl docker -go task.go
-
K8S部署yaml生成:
goctl kube deploy -name task -namespace my-ns -image task -o task-k8s.yaml -port 80 --serviceAccount find-endpoints
-
生成
Mongo Model
:goctl model mongo -type Task -c -style go_zero -d .
-
集成一个比较好用的log插件:目前使用logrus
-
Go-Zero自带链路追踪:Jaeger:[配置位置](./task/etc/task.yaml),仅需要在配置中添加`Telemetry`信息.配置位置,仅需要在配置中添加
Telemetry
信息. -
Opentelemetry+Jaeger链路追踪:[代码位置](./example/otel)代码位置
-
链路追踪+日志追踪:链路追踪有traceId,如果使用中间件获取每个request中的traceId,然后使用logrus的hook,日志打印过程中有traceId则添加,链路追踪会更加完善.
-
使用协程池处理一些并发较高的method或者逻辑
-
rabbitmq生产者消费者优化 TODO (断线重连优化)
-
casbin权限
-
try with [dtm](https://github.com/dtm-labs/dtm)[dtm](https://github.com/dtm-labs/dtm)
-
validate集成校验
-
华为obs集成
-
rpc中etcd服务,如果使用k8s部署,那么将直接使用target注册到k8s中,由k8s的服务发现处理
-
prometheus服务监控
-
集成mysql(use gorm)
-
集成mongo(zero原生支持的mgo)
-
go-zero PeriodLimit => 滑动窗口实现的限流器 => 当然go-zero也有基于令牌桶实现的限流器
-
微信定时向用户/群组发送消息,代码
-
go-zero自动生成swagger文件:
-
切换到task项目并执行:
goctl api plugin -plugin goctl-swagger="swagger -filename swagger.json" -api task.api
-
如果没有安装
goctl-swagger
,请先安装goctl-swagger
(用于生成Swagger文档的工具):go install github.com/zeromicro/goctl-swagger@latest
-
export PATH=$PATH:$(go env GOPATH)/bin
--> 将所有gopath/bin
下面的工具添加到全局变量中; -
source ./zshrc
--> 我用的oh my zsh,然后重新source即可 -
服务器或者本地安装swagger-ui,然后查看网页.
docker run -it -d --name swagger-ui -p 8080:8080 swaggerapi/swagger-ui
-
查看
swagger.json
文件:curl http://localhost:8888/task/swagger
,先把swagger.json
文件复制到镜像中,然后使用go:embed
把二进制文件读取出来,也可以使用ioutils.Readfile
;最后返回二进制文件流.
-
-
kafka客户端实现
-
elasticsearch客户端实现
-
使用swagger文件生成golang客户端代码 => `swagger-codegen generate -i swagger.json -l go -o ./gen`,具体使用见下方`根据swagger文件生成golang客户端`
swagger-codegen generate -i swagger.json -l go -o ./gen
,具体使用见下方根据swagger文件生成golang客户端
-
json优化:1.json.NewEncoder代替json.marshal;2.使用json.Encoder的底层缓冲区,减少内存分配和垃圾回收开销
-
有http请求的路由中新增log中间件,用于请求的path和消耗的时间;
-
TODO 写一个类似gptx的wechat发消息的命令行工具;加油!!!
以task服务为例
-
生成task的
Dockerfile
:goctl docker -go task.go
-
docker-compose
中添加task服务:然后:docker-compose build task
- pay
make api SVC=pay
- task
make api SVC=task
- pay
make json SVC=pay
- task
make json SVC=task
- pay
make swagger SVC=pay
- pay
make dockerfile SVC=pay
go-zero在处理multipart-formdata的结构时,如果path中有参数,formdata中也有参数,请参考import代码中的处理方法.