- 欢迎加入我的训练营:云原生 AI 实战营,一个助力 Go 开发者在 AI 时代建立技术竞争力的实战营。实战营中包含大量 Go、云原生、AI Infra 相关的优质实战课程和项目。
- 欢迎关注我的公众号:令飞编程,持续分享 Go、云原生、AI Infra 相关技术。
今天来分享一个超级优秀的 Go 实战项目(看了绝对不后悔)。该实战项目很轻量,但功能又很全,包括了 Go 项目开发中的核心功能设计和实现。
废话不多说,先贴上项目的源码仓库:github.com/onexstack/m…。温馨提示:记得 Star 更新不错过!
再来化几个重点:
- 项目架构好: 实战项目参考 Kuberentes 的软件设计,设计了独有的三层架构,可以大大简化项目开发的复杂度,提高项目开发的效率!
- 项目代码质量高: 项目中的每一个功能点都结合了我过去 10 年的 Go 项目开发经验,精雕细琢,力求在易读性、可维护性、可扩展性上做的最好!
- 更神奇的是:
- 项目有配套的完整课程: 项目有配套的完整课程(共 40 节课),从 0 到 1 给你详细介绍 Go 项目的构建思路和实现方法;
- 项目开发脚手架: 项目有一个跟其完全匹配的开发脚手架 osbuilder,该工具可以生成跟 miniblog 项目完全一致的 Go 项目。
总结来说就是: miniblog 项目在代码架构设计上、功能设计上、代码质量上都很高。并且通过提供 osbuilder 项目开发脚手架和完整的配套课程,让你知道 miniblog 项目开发的全思路和全过程,并且还能够很方便的一键生成一个新的兄弟项目。非常适合需要给简历添加一个优秀 Go 项目的开发者。其实也适合其他 Go 开发者!
实战项目介绍
本实战项目旨在帮助你快速掌握 Go 项目开发的核心知识,重点不在于具体的业务实现,而在于开发 Go 项目的方法与实践。为降低学习成本,同时提供足够的业务复杂度以承载 Go 项目开发的核心内容,本实战项目选择实现一个简化的博客系统(简称 miniblog)。选择博客系统作为实战项目的原因如下:
- 业务逻辑广泛熟知: 开发者几乎都撰写过博客,对写博客的基本流程已十分熟悉,因此可以快速理解本项目所要实现的业务功能;
- 业务逻辑简单: 项目功能仅包含博客系统的基本功能,如用户注册、登录,以及博客创建(仅包括标题和内容),从而降低了业务复杂度,使你能专注于核心开发知识的学习。
miniblog 项目实现了两大功能模块:用户管理和博客管理。用户管理包括用户注册、登录、获取用户列表与详情,更新用户信息及修改用户密码等操作。博客管理则提供创建博客、获取博客列表与详情,更新博客内容以及删除博客的功能。
miniblog 除了实现博客系统的基本功能外,还集成了许多 Go 项目开发中高频使用的技术和最佳实践,具体包括:
- 软件架构:采用三层简洁架构,确保项目结构清晰、易维护;
- 高频 Go 包:使用了 Go 项目开发中常用的 Go 包,如 gorm、casbin、govalidator、jwt-go、gin、cobra、viper、pflag、zap、pprof、grpc、protobuf、uuid、grpc-gateway、uuid、testify、sync、kratos 等;
- 目录结构:项目遵循 project-layout 规范,采用标准化的目录结构;
- 认证与授权:实现了基于 JWT 的认证和基于 Casbin 的授权功能;
- 日志与错误处理:设计了独立的日志包和错误包,设计了合理的错误返回方式及业务错误码;
- 构建与管理:使用高质量的 Makefile 对项目进行管理;
- 代码质量:通过 golangci-lint 工具对代码进行静态检查,确保代码处在一个较高的质量水平上;
- 测试覆盖:包含单元测试、性能测试、模糊测试和示例测试等多种测试案例;
- 丰富的 Web 功能:支持请求 ID、优雅关停、中间件、跨域处理、异常恢复等功能;
- 多种服务器类型:实现了 gRPC 服务器、HTTP 服务器和 HTTP 反向代理服务器;
- 多种数据交换格式:支持 JSON 和 Protobuf 数据格式;
- 开发规范:遵循多种开发规范,包括代码规范、版本规范、接口规范、日志规范、错误规范以及提交规范等;
- API 设计:接口设计遵循 RESTful API 规范,并提供 OpenAPI 3.0 和 Swagger 2.0 格式的 API 文档。
因此,miniblog 不仅是一个简单的博客系统,更是一个涵盖 Go 项目开发核心实践的优秀实战项目。
miniblog 简洁架构实现
任何实现简洁架构规定的五个约束的软件架构均可称为简洁架构。miniblog 项目参考业界简洁架构的实现,也设计实现了一种简洁架构。与其他简洁架构的最大区别在于,miniblog 的简洁架构设计更加简单实用,省略了一部分分层特性,仅保留了必要的分层,但带来了更大的易读性和可维护性。
miniblog 项目的简洁架构设计如下图所示。
整个软件架构一共分为以下三层:
- Handler 层: 负责 API 接口请求的参数解析、参数校验、业务逻辑处理分发、参数返回逻辑。在 Handler 层中,还有 Default 和 Validation 模块,分别用来给请求参数设置默认值,并校验请求参数的合法性;
- Biz 层: 包括了具体的业务逻辑实现。Biz 层根据 REST 资源类型分为不同的模块,内部可模块间交叉调用。在 Biz 层还有 Conversion 模块,用来进行结构体类型转换;
- Store 层: 数据访问层(包括访问数据库或第三方微服务),用来跟数据库/微服务交互执行数据的 CURD 操作。该层做了进一步的抽象,抽象出了通用的 Store 层,Generic Store 之上 REST 资源的数据存储操作,均可继承 Generic Store 的方法实现,而不需要自行再实现一套。
上图所示的简洁架构,还具有以下特点:
- 简洁架构提供了清晰的分层结构,各层功能明确,职责分明;
- 通过接口解耦每一层,从而实现代码的可测性、独立性和扩展性;
- 代码依赖由上向下(图中的有向箭头表示依赖规则),单向单层依赖,提供了清晰的依赖关系,使代码易于理解和维护。
上述三个特点也使得整个软件代码具有很高的易读性和可维护性。上图所示的简洁架构有三层,但这不意味着简洁架构只有三层。如果有需要你可以对层进行增减。虽然层数可变,但是依赖关系是固定的,即:单向依赖。
如何部署 miniblog 项目?
安装和配置分为以下四个步骤:
- miniblog 项目快速部署;
- 安装和配置 MariaDB 数据库;
- 安装和配置 miniblog 服务;
- 启动 Swagger API 文档。
miniblog 支持以下 2 种部署模式:
- 极速部署模式: 出了 Go 编译器,没有任何其他依赖;
- 标准部署模式: 通过标准方式部署 miniblog。
miniblog 项目安装和配置
安装好 Go 编译环境后,便可以开始部署 miniblog 项目。安装和配置分为以下四个步骤:
- miniblog 项目快速部署;
- 安装和配置 MariaDB 数据库;
- 安装和配置 miniblog 服务;
- 启动 Swagger API 文档。
miniblog 项目快速部署
miniblog 是一个教学项目。为了尽可能降低初始部署的复杂度,miniblog 提供了快速部署模式。你只需执行以下命令即可完成快速部署:
$ mkdir -p $GOPATH && cd $GOPATH
$ mkdir -p $HOME/golang/src/github.com/onexstack
$ cd $HOME/golang/src/github.com/onexstack
$ git clone -b v1.0.0 --depth=1 https://github.com/onexstack/miniblog
$ cd miniblog
$ go work init . # 初始化 Go 工作区
$ go work use . # 将 miniblog 项目添加到当前 Go 工作区中
$ make build BINS=mb-apiserver # 编译源码
$ _output/platforms/linux/amd64/mb-apiserver # 启动服务
$ curl http://127.0.0.1:5555/healthz # 测试是否成功安装(HTTPS 协议,新终端中执行)
{"timestamp":"2025-02-01 23:50:29"}
$ go run examples/client/health/main.go # 测试健康检查接口(gRPC 协议)
$ go run examples/client/user/main.go # 测试用户相关接口(gRPC 协议)
$ go run examples/client/post/main.go # 测试博客相关接口(gRPC 协议)
mb-apiserver 数据存储支持 SQLite 内存数据库和 MariaDB 数据库,默认采用 SQLite 内存数据库。在快速部署模式下,使用的也是 SQLite 内存数据库。如果你需要使用 MariaDB 数据库部署 miniblog,请继续阅读本节课内容。
安装和配置 MariaDB 数据库
在生产环境中,miniblog 项目需要使用 MariaDB 数据库来存储数据,因此需要先安装 MariaDB 数据库。安装和配置 MariaDB 的具体步骤如下:
(1)安装 MariaDB 服务端和 MariaDB 客户端
安装命令如下:
$ sudo apt install -y mariadb-server mariadb-client
(2)启动 MariaDB,并设置开机启动
启动命令如下:
$ sudo systemctl enable mariadb
$ sudo systemctl start mariadb
$ sudo systemctl enable mariadb
(3)设置 root 初始密码
初始化命令如下:
$ sudo mysqladmin -uroot password 'miniblog1234'
提示: 执行 mysqladmin 命令时,必须具有 root 权限,否则可能会出现错误:mysqladmin: connect to server at 'localhost' failed。
(4)登录数据库并创建 miniblog 用户
创建命令如下:
$ mysql -h127.0.0.1 -P3306 -uroot -p'miniblog1234'
> grant all on miniblog.* TO miniblog@127.0.0.1 identified by 'miniblog1234';
> flush privileges;
> exit;
(5)使用 miniblog 用户登录 MariaDB,并创建 miniblog 数据库
创建命令如下:
$ cd $HOME/golang/src/github.com/onexstack/miniblog
$ mysql -h127.0.0.1 -P3306 -u miniblog -p'miniblog1234'
> source configs/miniblog.sql;
> use miniblog;
Database changed
> show tables;
+--------------------+
| Tables_in_miniblog |
+--------------------+
| casbin_rule |
| post |
| user |
+--------------------+
3 rows in set (0.000 sec)
安装和配置 miniblog 服务
miniblog 服务的安装和配置分为以下几个步骤。
(1)安装配置文件、二进制文件
安装命令如下:
$ cd $HOME/golang/src/github.com/onexstack/miniblog
$ sudo mkdir -p /opt/miniblog/{data,bin,etc,log} # 创建需要的目录
$ make build BINS=mb-apiserver # 编译源码,生成 mb-apiserver 二进制文件
$ sudo cp _output/platforms/linux/amd64/mb-apiserver /opt/miniblog/bin
$ cp configs/mb-apiserver.yaml /tmp/
# 关闭 SQLite 内存数据库,启用 MariaDB
$ sed -i 's/memory-store:.*true/memory-store: false/' /tmp/mb-apiserver.yaml
$ sudo cp /tmp/mb-apiserver.yaml /opt/miniblog/etc/ # 安装更新后的配置文件
$ make ca # 创建 CA 文件
$ sudo cp -a _output/cert/ /opt/miniblog/etc/ # 安装 CA 文件
提示:miniblog 服务的启动二进制文件名为 mb-apiserver,而非 miniblog。
(2)通过 Systemd 启动 mb-apiserver 服务
启动命令如下:
$ sudo cp init/mb-apiserver.service /etc/systemd/system/mb-apiserver.service
$ sudo systemctl daemon-reload # 重新加载 Systemd Unit 文件
$ sudo systemctl restart mb-apiserver # 启动 mb-apiserver 服务
$ sudo systemctl enable mb-apiserver # 设置 mb-apiserver 服务开机启动(可选)
(3)测试 mb-apiserver 服务是否成功安装
测试命令如下:
$ curl -k https://127.0.0.1:5555/healthz # 测试是否成功安装(HTTPS 协议)
{"timestamp":"2025-02-01 03:57:11"}
如果终端输出{"timestamp":"2025-02-01 03:57:11"},说明 miniblog 安装成功。
由于在使用 Systemd 部署 mb-apiserver 时启用了 TLS,因此以下命令无法用于测试,因为它们使用的是非 TLS 通信模式:
$ go run examples/client/health/main.go # 测试健康检查接口(gRPC 协议)
$ go run examples/client/user/main.go # 测试用户相关接口(gRPC 协议)
$ go run examples/client/post/main.go # 测试博客相关接口(gRPC 协议)
启动 Swagger API 文档
此外,你还可以使用 swagger 命令启动在线 Swagger API 文档,具体命令如下:
$ make swagger # 自动生成 Swagger API 文档
$ make serve-swagger
2025/02/01 00:59:10 serving docs at http://localhost:65534/docs
之后,你可以通过访问 http://localhost:65534/docs 查看 Swagger API 文档。