Go框架三件套详解(1月20日) | 青训营笔记

187 阅读6分钟

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

一、本堂课重点内容:

1. 三件套(Grom、Kitex、Hertz)介绍
2. 三件套使用
3. 实战案例介绍

二、详细知识点介绍:

1. 三件套(Grom、Kitex、Hertz)介绍
  • Gorm

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

  • Kitex

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

  • Hertz

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

2. 三件套使用

2.1 Gorm的使用

定义结构体

第一步,进行orm操作前必须有个结构体,用于承载或表示一条数据。通过一条数据也可以看到所在表的表结构,现在新建一张表。结构如下:

type UserInfo struct {
	Id     int `gorm:"primaryKey"`
	Name   string
	Gender string
	Hobby  string
}

字段的tag可以指定数据的类型和索引。

连接mysql,通过gorm新建表

dsn结构:"用户名:密码@(数据库连接:端口)/数据库名称?charset=字符集&parseTime=True&loc=Local"

代码如下:

dsn := "root:root123@(localhost:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
    panic(err)
}
// 跑一下数据库迁移,如果不存在则新建表,存在判断字段是否一致不一致修改。
db.AutoMigrate(&ormdemo.UserInfo{})

新建的表命名是类名大驼峰转下划线,最后加上一个s,例如以上案例生成的是user_infos

新增一条数据

db.Create方法可以新建一条数据,传入的是一个表结构体指针,返回值是一个gorm.DB,即我们的数据库连接。如下:

db.Create(&ormdemo.UserInfo{
    Name:   "jaylog",
    Gender: "man",
    Hobby:  "pingpong",
})

数据库就新加一条数据了

create.png

查询一条数据

查询的方法挺多个,这里先使用一个官网的快速开始案例db.First(),参数是一个结构体指针,查询到的话会把数据保存到结构体中。

var u = &ormdemo.UserInfo{}
// 用来存放结果的结构体,第二个参数,id
db.First(u, 1)
fmt.Println(u.Name)
// go run .\main.go
//  jaylog

修改一条数据

查询到一条数据,修改他的一个字段。需要先查询到才可以修改

var u = &ormdemo.UserInfo{}
db.First(u, 1).Update("hobby", "running")
fmt.Printf("姓名:%s,爱好:%s", u.Name, u.Hobby)
// 姓名:jaylog,爱好:running
var u = &ormdemo.UserInfo{}
db.First(u, 1)
db.Model(u).Uodate("hobby", "running")
fmt.Printf("姓名:%s,爱好:%s", u.Name, u.Hobby)
// 姓名:jaylog,爱好:running
复制代码

删除一条数据

使用db.Delete(&u,1)

db.Delete(&u, 1)
// 删除一条id为1的数据

GORM事务

  • Gorm提供了Begin、Commit、Rollback方法用于使用事务。

    index.png

  • Gorm提供了Tansaction方法用于自动提交事务,避免用户漏写Commit、Rollback。

    index.png

GORM Hook

Hook是在创建、查询、更新、删除等操作之前、之后自动调用的函数。

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

image.png

GORM性能提高

对于写操作(创建、更新、删除),为了确保数据的完整性,GORM会将它们封装在事务内运行。但这会降低性能,你可以使用SkipDefaultTransaction关闭默认事务。

使用PrepareStmt缓存预编译语句可以提高后续调用的速度。

image.png

2.2 Kitex的使用

框架特点

  • 高性能

使用自研的高性能网络库 Netpoll,性能相较 go net 具有显著优势。

  • 扩展性

提供了较多的扩展接口以及默认扩展实现,使用者也可以根据需要自行定制扩展,具体见下面的框架扩展。

  • 多消息协议

RPC 消息协议默认支持 ​Thrift​、​Kitex Protobuf​、​gRPC​。Thrift 支持 Buffered 和 Framed 二进制协议;Kitex Protobuf 是 Kitex 自定义的 Protobuf 消息协议,协议格式类似 Thrift;gRPC 是对 gRPC 消息协议的支持,可以与 gRPC 互通。除此之外,使用者也可以扩展自己的消息协议。

  • 多传输协议

传输协议封装消息协议进行 RPC 互通,传输协议可以额外透传元信息,用于服务治理,Kitex 支持的传输协议有 ​TTHeader​、​HTTP2​。TTHeader 可以和 Thrift、Kitex Protobuf 结合使用;HTTP2 目前主要是结合 gRPC 协议使用,后续也会支持 Thrift。

  • 多种消息类型

支持 ​PingPong​、​Oneway​、双向 ​Streaming​。其中 Oneway 目前只对 Thrift 协议支持,双向 Streaming 只对 gRPC 支持,后续会考虑支持 Thrift 的双向 Streaming。

  • 服务治理

支持服务注册/发现、负载均衡、熔断、限流、重试、监控、链路跟踪、日志、诊断等服务治理模块,大部分均已提供默认扩展,使用者可选择集成。

  • 代码生成

Kitex 内置代码生成工具,可支持生成 ​Thrift​、​Protobuf ​以及脚手架代码。

2.3 Hertz的使用

  • 高易用性

    在开发过程中,快速写出来正确的代码往往是更重要的。因此,在 Hertz 在迭代过程中,积极听取用户意见,持续打磨框架,希望为用户提供一个更好的使用体验,帮助用户更快的写出正确的代码。

  • 高性能

    Hertz 默认使用自研的高性能网络库 Netpoll,在一些特殊场景相较于 go net,Hertz 在 QPS、时延上均具有一定优势。关于性能数据,可参考下图 Echo 数据。

  • 高扩展性

    Hertz 采用了分层设计,提供了较多的接口以及默认的扩展实现,用户也可以自行扩展。同时得益于框架的分层设计,框架的扩展性也会大很多。目前仅将稳定的能力开源给社区,更多的规划参考 RoadMap

  • 多协议支持

    Hertz 框架原生提供 HTTP1.1、ALPN 协议支持。除此之外,由于分层设计,Hertz 甚至支持自定义构建协议解析逻辑,以满足协议层扩展的任意需求。

  • 网络层切换能力

    Hertz 实现了 Netpoll 和 Golang 原生网络库 间按需切换能力,用户可以针对不同的场景选择合适的网络库,同时也支持以插件的方式为 Hertz 扩展网络库实现。

3. 实战案例介绍

使用Hertz、Kitex、Gorm搭建出来的具备一定业务逻辑的后端API项目。

image.png

index.png

index-1.png

三、实践练习例子:

参考:github.com/cloudwego/b…

四、课后个人总结:

经过本次课程的学习,我了解到基本的Go框架三件套的使用方法,但是还没有真正实现上手,还得多做做试验,刚开始看这部分还是感觉比较困难的,再仔细学几天,看能不能写懂代码~

五、引用参考: