三件套介绍
Gorm
Gorm是一个已经迭代了10年+的功能强大的ORM框架
Kitex
Kitex是字节内部的Golang微服务RPC框架,具有高性能、强可扩展的主要特点。支持多协议并且拥有丰富的开源扩展
Hertz
Hertz是字节内部的HTTP框架,参考了其它开源框架的优势,结合字节跳动内部的需求,具有高易用性、高性能、高扩展特点
三件套的使用
Gorm的基本使用
type Product struct{
Code string
Price uint
}
func ()p Product TableName() string{
return "product"
}
func main(){
db, err := gorm.Open(
mysql.Open()
&gorm.Config{} //连接数据库
)
if err != nil{
panic("failed to connecct database")
}
db.Create(&Product{Code:"042",Price: 100}) //创建数据
//查询数据
var product Product
db.First(&product,1) //根据整形主键查找
db.First(&product,"code = ?","042") //查找Code字段为 420 的记录
//更新数据
db.Model(&product).Update("Price",200)
//更新多个数据
db.Model(&product).Updates(Product{Price: 200,Code: "F42"}) //仅仅更新非零值字段
db.Model(&product).Updates(map[string]interface{}{"Price": 200,"Code": "F42"})
//删除数据
db.Delete(Product, 1)
}
Kitex
Kitex 典型的使用场景就是基于thrift定义的IDL来定义服务接口,实现客户端和服务端的通信
namespace go api
struct Request {
1: string message1
2: string message2
}
struct Response {
1: string message
}
service KStudy {
Response Concat(1: Request req)
}
这个地方定义了一个KStudy服务,包含一个Concat接口,语义是将Request中的message1和message2两个字符串拼接起来,通过Response返回
kitex_gen这个目录下包含了kitex为client和server生成的代码
handler.gokitex自动基于我们的IDL定义,生成了一个server接口的空实现
server实现
// Concat implements the KStudyImpl interface.
func (s *KStudyImpl) Concat(ctx context.Context, req *api.Request) (resp *api.Response, err error) {
resp = api.NewResponse()
resp.Message = req.GetMessage1() + req.GetMessage2()
return
}
Client
我们在 kstudy 下新建client文件夹,用于实现客户端相关逻辑。新增 main.go 作为客户端的启动入口。由于我们目前只是单机的 server 和 client 交互,没有复杂的服务发现逻辑,需要通过添加client.Option来指定调用的 host 和 port。
package main
import (
"context"
"log"
"github.com/ag9920/kstudy/kitex_gen/api"
"github.com/ag9920/kstudy/kitex_gen/api/kstudy"
"github.com/cloudwego/kitex/client"
)
func main() {
client, err := kstudy.NewClient("kstudy", client.WithHostPorts("0.0.0.0:8888"))
if err != nil {
log.Fatal(err)
}
req := &api.Request{
Message1: "message1",
Message2: "message2",
}
resp, err := client.Concat(context.Background(), req)
if err != nil {
log.Fatal(err)
}
log.Println(resp)
}
最后输出的结果
Response({Message:message1message2})
这样就完成了一次client => server 调用
Kitex实现流程
现在,来了解一下RPC服务的基本工作流程,大多数有关RPC的文章都会提到这个。
基本都是像下图一样,先是根据配置初始化服务,然后服务启动,启动后监听端口,当有请求进来时,将字节码反序列化,进入业务处理,处理完之后再编码成字节码在网络中传回给RPC客户端。
Hertz
Hertz从上到下分为:应用层、路由层、协议层和传输层,每一层各司其职,统一抽象到公共层,做到跨层复用。
另外,同主库发布的还有作为子模块的Hz脚手架,它能够协助使用者快速搭建出项目核心骨架以及提供使用的构建工具链。
应用层
应用层是和用户直接交互的一层,提供丰富易用的 API,主要包括 Server、Client 和一些其他通用抽象。Server 提供了注册 HandlerFunc、Binding、Rendering 等能力;Client 提供了调用下游和服务发现等能力;以及抽象一个 HTTP 请求所必须涉及到的请求(Request)、响应(Response)、上下文(RequestContext)、中间件(Middleware)等等。
路由层
路由层负责根据 URI 匹配对应的处理函数。
协议层
协议层负责不同协议的实现和扩展。
传输层
传输层负责底层的网络库的抽象和实现。
Hz脚手架
与 Hertz 一并开源的还有一个易用的命令行工具 Hz,用户只需提供一个 IDL,根据定义好的接口信息,Hz 便可以一键生成项目脚手架,让 Hertz 达到开箱即用的状态。
Common组件
Common 组件主要存放一些公共的能力,比如错误处理、单元测试能力、可观测性相关能力(Log、Trace、Metrics 等)。对于服务可观测性的能力,Hertz 提供了默认的实现,用户可以按需装配;如果用户有特殊的需求,也可以通过 Hertz 提供的接口注入。
参考文章: