硬核来袭:分享一个超级优秀的 Go 实战项目,不优秀接受板砖!

168 阅读9分钟
  • 欢迎加入我的训练营:云原生 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 项目?

安装和配置分为以下四个步骤:

  1. miniblog 项目快速部署;
  2. 安装和配置 MariaDB 数据库;
  3. 安装和配置 miniblog 服务;
  4. 启动 Swagger API 文档。

miniblog 支持以下 2 种部署模式:

  • 极速部署模式: 出了 Go 编译器,没有任何其他依赖;
  • 标准部署模式: 通过标准方式部署 miniblog。

miniblog 项目安装和配置

安装好 Go 编译环境后,便可以开始部署 miniblog 项目。安装和配置分为以下四个步骤:

  1. miniblog 项目快速部署;
  2. 安装和配置 MariaDB 数据库;
  3. 安装和配置 miniblog 服务;
  4. 启动 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 文档。