Skip to content

zjzjzjzj1874/best-practice-go-zero

Repository files navigation

best-practice-go-zero

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模块

go-zero usage

How to create a service/project:

  • exec goctl api new my_zero,then you will see a new service named my-zero.

start with microservice

user-rpc

  • if protoc,protoc-gen-go,protoc-gen-rpc-go are not installed, try with goctl 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

Run with api file

  • cd into target file && exec goctl api go -api my_zero.api -style goZero -dir .

Create a Dockerfile

  • cd into target file && exec goctl docker -go my-zero.go

migrate or autogen model?

  • 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.

goctl实用小技巧

  • 根据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 .

TODO list

  • 集成一个比较好用的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也有基于令牌桶实现的限流器

  • 微信定时向用户/群组发送消息,代码

  • 火山引擎翻译API调用,官方网站,代码

  • 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发消息的命令行工具;加油!!!

project deploy

部署步骤

以task服务为例

  • 生成task的Dockerfile:goctl docker -go task.go

  • docker-compose中添加task服务:然后:docker-compose build task

api脚手架生成代码

  • pay
make api SVC=pay
  • task
make api SVC=task

swagger json文件生成

  • pay
make json SVC=pay
  • task
make json SVC=task

根据swagger文件生成golang客户端

  • pay
make swagger SVC=pay

Dockerfile生成

  • pay
make dockerfile SVC=pay

其他依赖

微信支付

参考资料

其他说明

go-zero在处理multipart-formdata的结构时,如果path中有参数,formdata中也有参数,请参考import代码中的处理方法.

About

go-zero最佳实践

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published