Go Frame介绍
GoFrame 是一款模块化、高性能的Go 语言开发框架。无论是组件库、单体服务、微服务都可以使用GoFrame来编写;GoFrame 提供开箱即用、丰富强大的基础组件库;
可根据代码结构自动生成清晰、规范的接口文档,节省人工编写时间,提高文档与代码的同步性和准确性。
高效便捷的代码生成工具链,极大提高开发效率,减少重复性工作,同时保证代码的规范性和一致性。
环境准备
- 搭建go环境变量,我这里使用的目前最新版本: 1.26.1
- go frame 版本 2.10.0
- Postman、Apipost 7.2.1 以上版本(任选其一即可,需要支持grpc测试功能)
- Protobuf 下载地址:https://github.com/protocolbuffers/protobuf/releases
- etcd 作为注册中心使用
- mysql 5.7 持久化存储能力
安装环境
安装grpc
# 生成数据模型代码 go install google.golang.org/protobuf/cmd/protoc-gen-go@latest # 生成接口代码 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest安装 go frame cli工具
go install github.com/gogf/gf/cmd/gf/v2@latest安装 protobuf
下载地址:https://github.com/protocolbuffers/protobuf/releases。根据自己的系统选择,我的是win11系统,所以选择win64 的压缩包就可以了,
下载后解压到某个目录,并配置环境变量;然后输入以下命令能正常显示版本号就行了
D:\tools\protoc-36.0-win64\bin>protoc --version libprotoc 36.0创建数据库
CREATE DATABASE `user`; CREATE DATABASE `word`;搭建
搭建微服务文档:https://goframe.org/course/proxima-book
1、项目初始化
我们要创建单体式的微服务,既有
先用 cli工具创建2个工程
gf init web-service gf init user-service- gf:GoFrame 的 CLI 脚手架命令工具
- init:初始化项目脚手架
- web-service:工程名称(仓库名),会生成 ./web-service/ 目录
三种创建工程模式的本质区别
gf init proxima不带任何参数(普通单仓 single‑repo)
✅同时生成:根目录go.mod+main.go,一个仓库 = 一个可执行服务。gf init proxima -m(‑m = mono 大仓根仓库)
✅ 生成顶层go.mod;❌没有 main.go。
大仓是存放多个微服务的容器,根目录不做可执行程序,真正的入口在
app/*各个子服务里面。
gf init app/user -a(‑a = monoApp,大仓内部新增子服务)
✅ 生成子服务代码、cmd命令;❌没有 go.mod,复用大仓顶层的go.mod。
总结:
-m:有go.mod,无main.go(大仓根)-a:有main入口代码,无go.mod(大仓子应用)- 不带参数:同时有go.mod + main.go,普通独立项目
2、安装组件
注意:因为web-service 和 user-service 都是独立的工程,他们俩互不相关,所以需要在 web-service 和 user-service 下都执行以下2命令,切记!
安装微服务组件
安装grpcx组件,让GoFrame支持微服务开发。
go get -u github.com/gogf/gf/contrib/rpc/grpcx/v2安装etcd组件
安装etcd组件,提供服务注册功能。如果使用本地服务发现,可以不安装etcd;
go get -u github.com/gogf/gf/contrib/registry/etcd/v23、user-service 工程完善
将下列文件全部删除,留下一个空白的环境。
user-service/api/* user-service/internal/controller/*3.1、安装驱动
先将 user-service 工程完善后在搭建web-service剩余工作
进入 user-service 目录
cd user-service因为 web-service 只负责对内外接口的中转,不涉及到业务逻辑和数据库,所以只需要在 user-service 下安装数据库驱动即可
安装数据库驱动
和单体服务一样,也需要安装对应的数据库驱动,这里演示的是MySQL。
go get -u github.com/gogf/gf/contrib/drivers/mysql/v23.2、编写proto协议文件
创建一个名为account/v1的目录,管理用户账号相关业务。
user-servicer/manifest/protobuf/account/v1/account.proto
syntax = "proto3"; package account.v1; option go_package = "user-service/api/account/v1"; service Account{ rpc UserRegister(UserRegisterReq) returns (UserRegisterRes) {} } message UserRegisterReq { string username = 1; // v:required|min-length:2 string password = 2; // v:required|min-length:6 string email = 3; // v:required|email } message UserRegisterRes { int32 id = 1; }简单的介绍一下proto语法:
- syntax 规定本文件语法版本;
- package 定义的是服务命名空间,可以理解为包名;
- option 设定编译选项,go_package指定生成的Go代码所属的包名。在GoFrame中固定格式是项目名 + app + 微服务名称 + api + 模块名 + v1;
- service 定义远程调用方法,一般是RPC,规定其请求和响应参数;
- message 定义数据结构,string是数据类型,username是字段名,赋值号后面的递增数字是字段编号。最后面的注释是框架提供的参数校检,使用方式普通的HTTP接口一致。
我们的文件定义了以下内容:
- 使用proto3语法版本的定义;
- 定义了包名为account.v1;
- 设置了Go代码生成的包路径选项go_package为 api/account/v1;
- 定义了一个Account服务,包含一个RPC方法UserRegister,它接受UserRegisterReq消息- 并返回UserRegisterRes消息;
- 定义了一个消息类型UserRegisterReq,包含三个字段:
- username (字符串类型,编号为1)
- password (字符串类型,编号为2)
- email (字符串类型,编号为3)
- 定义了一个消息类型UserRegisterRes,包含一个字段:
- id (整型,编号为1)
3.3 根据proto协议文件生成go代码
协议文件写好之后,执行gf gen pb命令即可生成代码
D:\tools\protoc-36.0-win64\bin\protoc.exe --proto_path=D:\projects\go-frame_lern\go-frame-microservice\user-service\manifest\protobuf --go_out=paths=source_relative:D:\projects\go-frame_lern\go-frame-microservice\user-service\api --go-grpc_out=paths=source_relative:D:\projects\go-frame_lern\go-frame-microservice\user-service\api D:\projects\go-frame_lern\go-frame-microservice\user-service\manifest\protobuf\account.proto done!3.4、修改cmd.go
gf init 生成的服务是基于http的,因为我们用的grpc,所以需要修改为grpc 的服务,为了方便调试,这里不用 etcd,直接用本地联调,关键代码:c.Address = ":8001"
package cmd import ( "context" "github.com/gogf/gf/contrib/rpc/grpcx/v2" "google.golang.org/grpc" "user-service/internal/controller/account" "github.com/gogf/gf/v2/os/gcmd" ) var ( Main = gcmd.Command{ Name: "main", Usage: "main", Brief: "start http server", Func: func(ctx context.Context, parser *gcmd.Parser) (err error) { c := grpcx.Server.NewConfig() // gRPC 本地联调,不使用注册中心 c.Address = ":8001" c.Options = append(c.Options, []grpc.ServerOption{ grpcx.Server.ChainUnary( grpcx.Server.UnaryValidate, )}..., ) s := grpcx.Server.New(c) // 注册 account ,以便可以被其他服务发现 account.Register(s) s.Run() return nil }, } )如果不想在代码写死:c.Address = ":8001",也可以在配置文件manifest/config.yaml加上以下配置,效果是一样的
grpc: address: ":8001" # 不填 registry 配置,就不会启用注册中心! # registry: 这一行直接删掉,不要配置etcd/nacos3.5、启动并测试
找到 main.go,运行main方法,显示以下内容,就表示已经成功了
测试接口,生成的controller 接口默认情况下去请求会报错,改一下,让他能够正常返回数据,user-service/internal/controller/account/account.go
使用go代码模拟客户端进行调用
在服务根目录下创建一个test目录,里面在创建一个 grpc_client_test.go 文件
grpc_client_test.go文件内容
packagemainimport("context""fmt""testing""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure"v1"user-service/api/account/v1")funcTest_grpc_client(t*testing.T){// 本地直连,insecure关闭tlsconn,err:=grpc.Dial("127.0.0.1:8001",grpc.WithTransportCredentials(insecure.NewCredentials()),)iferr!=nil{panic(err)}deferconn.Close()client:=v1.NewAccountClient(conn)// 请求resp,err:=client.UserRegister(context.Background(),&v1.UserRegisterReq{Username:"test001",Password:"123456",Email:"test@demo.com",})iferr!=nil{fmt.Println("调用失败:",err)return}fmt.Printf("返回id=%d\n",resp.Id)}运行后会自动请求user 服务,返回以下内容表示成功
4、web-service 工程完善
5、启动服务并调用
GoFrame v2.x+ 最新官方标准目录结构
这是gf cli 自动生成的纯原版结构,无任何旧版内容,企业生产环境唯一标准结构,我给你整理成最清晰、最实用、能直接照着开发的版本。
一、完整标准目录树
你的项目/ ├── api/ # 对外 API 契约(入参/出参/路由定义) ├── hack/ # 框架工具链配置(gf 命令依赖) ├── internal/ # 项目核心私有代码(外部不可访问) │ ├── cmd/ # 服务启动入口 │ ├── consts/ # 全局常量(错误码、状态、配置key) │ ├── controller/ # HTTP 请求控制器 │ ├── dao/ # 数据库操作层 │ ├── logic/ # 业务逻辑实现层 │ ├── model/ # 数据模型 │ │ ├── do/ # 数据操作对象(业务层用) │ │ └── entity/ # 数据库表映射实体 │ ├── packed/ # 资源打包文件(自动生成) │ └── service/ # 服务接口定义 ├── manifest/ # 部署&配置文件 │ ├── config/ # 多环境配置(dev/prod) │ ├── deploy/ # 部署脚本(k8s/pm2) │ └── docker/ # Docker 构建文件 ├── resource/ # 静态资源(模板、配置、静态文件) ├── utility/ # 项目通用工具函数 ├── go.mod # Go 模块依赖 ├── go.sum # 依赖版本锁定 ├── main.go # 项目唯一启动入口 └── Makefile # 构建命令快捷方式二、每个目录 + 文件 官方作用(纯新版)
1. 根目录文件
main.go
项目唯一启动入口。
- 只做一件事:调用
internal/cmd启动服务 - 无业务代码
go.mod/go.sum
Go 模块依赖管理,记录 GoFrame 及第三方库版本。
Makefile
快捷构建命令:
make run make build make gen不用记长命令。
2.api/—— 对外 API 契约(最重要)
GoFrame v2 核心设计:接口优先
- 所有接口入参、出参、路由、请求方法、参数校验全部在这里定义
- 控制器、文档、校验 全部自动生成
- 结构示例:
api/ ├── user/ │ └── v1/ │ └── user.go └── order/ └── v1/ └── order.go- 不写业务逻辑,只定义接口协议
3.hack/—— 框架工具链配置
gf 命令自动生成和构建依赖的配置
- 不用手动修改
- 包含:代码生成模板、构建配置、自定义命令
文件:
hack/ ├── config.yaml ├── hack.mk └── hack-cli.mk4.internal/—— 项目核心(Go 强制私有,外部无法引用)
这是所有业务代码存放地,最安全、最标准。
🔹internal/cmd/—— 服务启动入口
项目真正的启动逻辑:
- 初始化配置
- 注册路由
- 启动 HTTP 服务
- 支持多命令(http / rpc / cron)
🔹internal/consts/—— 全局常量
统一管理:
- 错误码
- 业务状态(1=启用,2=禁用)
- 配置 Key
- 全局固定值
避免魔法值,规范必备。
🔹internal/controller/—— 控制器
请求入口层
- 接收 HTTP 请求
- 自动参数校验
- 调用 service
- 返回响应
- 不写任何业务逻辑
- 可通过
gf gen ctrl自动生成
🔹internal/service/—— 服务接口
定义业务接口,给 controller 调用。
- 接口定义
- 解耦 controller 和 logic
- 便于测试、替换实现
🔹internal/logic/—— 业务逻辑(核心)
80% 业务代码都在这里
- 业务流程
- 数据计算
- 调用 dao
- 调用第三方服务
- 事务控制
🔹internal/dao/—— 数据库操作层
只做数据库 CRUD
- 自动生成(
gf gen dao) - 无业务逻辑
- 安全、规范、统一
🔹internal/model/—— 数据模型(v2 新标准)
分为两个绝对清晰的部分:
model/entity/
- 数据库表结构一一映射
- 自动生成
- 不允许手动修改
model/do/
- Data Object
- 业务层数据传输对象
- 用于 logic / service 之间数据传递
- 可自由扩展字段
🔹internal/packed/
资源打包目录
gf pack自动生成- 把配置、静态文件打包进二进制
- 支持单文件部署
5.manifest/—— 部署&配置
manifest/config/
多环境配置:
- config.yaml
- config.dev.yaml
- config.prod.yaml
包含:server、database、redis、logger、jwt 等。
manifest/deploy/
K8s、Nginx、systemd 部署文件。
manifest/docker/
Dockerfile、docker-compose 构建配置。
6.resource/—— 静态资源
存放:
- 模板文件
- 静态文件(html/css/js)
- 配置文件
- 证书
7.utility/—— 工具函数
项目内部通用工具:
- 字符串处理
- 加密
- 时间工具
- 自定义公共函数
三、GoFrame v2 标准请求流程(必背)
客户端请求 → 控制器(controller) → 服务接口(service) → 业务逻辑(logic) → 数据库操作(dao) → 数据模型(entity/do)一句话分层记忆:
- controller:收请求
- service:定接口
- logic:写业务
- dao:操作库
- api:定义参数
四、最常用的 4 条命令(新版标准)
gf run main.go# 启动项目gf gen ctrl# 根据 api 自动生成控制器gf gen dao# 根据数据库自动生成 dao/entitygf swagger# 生成接口文档五、这个结构为什么是官方最佳?
- internal 强制私有:业务代码绝对安全
- api 优先:接口定义统一,自动校验、自动文档
- 彻底分层:controller/service/logic/dao 标准四层架构
- 自动生成:90% 重复代码不用手写
- 多环境天然支持:开发/测试/生产配置隔离
- 部署标准化:docker / k8s 直接用
缺点
缺少以下微服务组件
- 熔断器
- 分布式锁
- 分布式事务