Go框架三件套 | 青训营笔记

102 阅读6分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天

一、本堂课重点内容

  • 三件套(GORM、Kitex、Hertz)介绍
  • 三件套的使用
  • 实战案例介绍

二、详细知识点介绍

三件套介绍

GORM

GORM是一个已经迭代了10年+的功能强大的ORM框架,在字节内部被广泛使用并且拥有非常丰富的开源扩展。

Kitex

Kitex是字节内部的Golang微服务RPC框架,具有高性能、强可扩展的主要特点,支持多协议并且拥有丰富的开源扩展。

Hertz

Hertz是字节内部的HTTP框架,参考了其他开源框架的优势,结合字节跳动内部的需求,具有高易用性、高性能、高扩展性特点。

三件套的使用

GORM

GORM 基础使用

image.png 其中 Product为定义的 gorm modelTableName()为实现的方法,从而定义表名,在结构体中,常添加 gorm.Model来实现一些基本的字段(如ID、CreatedAt等),在 main函数中使用 gorm.Open()来开启一个数据库连接,第一个参数配置各种数据库的驱动,此处使用的是mysql,第二个参数用于设置连接的配置。

之后便可以进行CRUD操作。

GORM 支持的数据库

目前GORM支持的数据库包括MySQL、SQL Server、PostgreSQL、SQLite,配置方法如上述基础使用中 gorm.Open()描述的第一个参数所示。

除此之外,若需要连接其他类型的数据库,可以复用或自行开发驱动。

GORM 相关的CRUD操作

具体可以参考GORM文档

GORM 事务

GORM提供了 BeginCommitRollback方法用于事务。

image.png

除此之外,还提供了 Transaction方法用于自动提交事务,避免漏写 CommitRollback

image.png

GORM Hook

GORM还提供了CRUD的Hook能力,其为创建、查询、更新、删除等操作之前、之后自动调用的函数。

如果任何Hook返回了错误,GORM将停止后续操作并回滚。

使用方法还请参考GORM Hook

GORM 性能提高

对于创建、更新、删除,为了确保数据的完整性,GORM会将它们封装在事务内运行。但是会降低一定的性能,可以使用SkipDefaultTransaction关闭默认事务(加在之前 gorm.Open()的第二个参数里)。

使用PrepareStmt可以缓存预编译语句来提高后续调用的速度,同样加在 gorm.Open()的第二个参数里。

GORM 生态

常用扩展

扩展名地址
GORM 代码生成工具github.com/go-gorm/gen
GORM 分片库方案github.com/go-gorm/sha…
GORM 手动索引github.com/go-gorm/hin…
GORM 乐观锁github.com/go-gorm/opt…
GORM 读写分离github.com/go-gorm/dbr…
GORM OpenTelemetry扩展github.com/go-gorm/ope…

更多请参考GORM文档

GORM 使用注意事项

  1. 字段默认值使用go tag来定义,`gorm:"default:xxx"`
  2. 使用 First查询时,若查不到数据会返回 ErrRecordNotFound
  3. 使用 Find查询时,查询不到不会返回错误。
  4. 当使用结构体作为查询条件(Where)时,GORM只会查询非零值字段(防止未赋值),因此,字段为零值的(0、""、false等)将不会用于构建查询条件,要将其用于构建查询条件时,需要使用Map来构建查询条件。
  5. Update语句中使用结构体时,只会更新非零值,如果需要更新零值可以使用Map更新或使用Select选择字段。
  6. GORM提供了 gorm.DeletedAt来帮用户实现软删。拥有软删的Model调用 Delete时,记录不会真正从数据库中删除,但是会将其DeletedAt设置为当前时间,并且无法通过正常查询找到该记录。要查询该软删记录,可以使用 Unscoped

Kitex

Kitex目前对Windows支持尚不完善,代码生成工具只能在Linux下运行。

定义IDL

如果需要进行RPC,就需要知道对方的接口是什么,需要传递什么参数,同时也要知道返回值是什么。此时就需要使用IDL来约定双方的协议,就像写代码时调用函数,需要知道函数签名一样。

namespace go api
struct Request {
    1: string message
}

struct Response {
    1: string message
}

service Echo {
    Response echo(1: Request req)
}

Kitex 生成代码

使用 kitex -module example -service example echo.thrift来生成代码。

image.png 得到与上图类似的目录结构。

  • build.sh是用于构建项目的脚本
  • kitex_gen是IDL内容相关的生成代码,主要是基础的Server/Client代码
  • main.go是程序的入口
  • handler.go是用户要实现的service方法(IDL中定义的)

Kitex 使用方法

参考Kitex 文档

Kitex 生态

常用扩展

扩展名地址
XDS 扩展github.com/kitex-contr…
opentelemetry 扩展github.com/kitex-contr…
ETCD 服务注册与发现扩展github.com/kitex-contr…
Nacos 服务注册与发现扩展github.com/kitex-contr…
Zookeeper 服务注册与发现扩展github.com/kitex-contr…
polaris 扩展github.com/kitex-contr…
丰富的示例代码与业务Demogithub.com/cloudwego/k…

Hertz

Hertz 基础使用

image.png 上述为Hertz实现的,该服务监听8080端口并注册了一个GET方法的路由函数。

Hertz 路由

Hertz提供了GET、POST、PUT、DELETE、ANY等方法用于注册路由,如下图所示。

image.png

此外,Hertz还提供了路由组(Group)的能力,用于支持路由分组的功能

image.png

此外,还提供了参数路由和通配路由,路由的优先级从大到小依次为:

  • 静态路由
  • 命名路由
  • 通配路由

Hertz 参数绑定

Hertz提供了Bind、Validate、BindAndValidate函数用于进行参数绑定和校验。

image.png

Hertz 中间件

Hertz 的中间件主要分为客户端中间件和服务端中间件,比如:

image.png

Hertz 代码生成工具

Hertz 提供了代码生成工具hz,通过IDL文件就可以生成对应的基础服务代码。

Hertz 更多内容

参考Hertz 文档

三、实践练习例子

项目介绍

在这次课程中介绍了一个Easy Note的实践项目。

其为使用Hertz、Kitex、GORM搭建,具有一定的业务逻辑的后端API项目。

下面的是服务使用到的相关技术:

服务名称服务介绍传输协议主要技术栈
demoapiAPI服务HTTPKitex/Hertz
demouser用户数据管理ThriftGORM/Kitex
demonote笔记数据管理ThriftGORM/Kitex

调用关系

easy-note-arch.png

更多内容

  • 原项目地址:Easy Note
  • 我的实践项目地址:my-easy-note(包含详细构建过程及注意事项)

四、课后个人总结

此次课程讲解了Golang中三个框架的使用以及注意事项,并给出了一个实践项目来巩固所学知识,所给出的实践项目有一些小问题,不过在查询资料之后都能够解决。

总的来说,这次课程的收获很大,对框架的理解也是更进一步了。

五、引用参考