这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天
今日笔记内容: 后端三件套 gorm, kitex, Hertz.
gorm通过昨天的笔记已经进行了学习, 在此略过
Kitex 和 Hertz 都属于 CloudWeGo 项目, 它是字节开源的一系列go/rust语言下高性能的云原生中间件实践. Kitex是RPC框架, Hertz是Http框架.
Kitex
RPC既远程过程调用. 是一种主流的后台微服务之间的通信调用方式, 通过IDL定义并提供接口, 向注册中心注册接口或提供服务发现能力, 并向外暴露一系列观测接口监听服务状态. 底层以二进制协议传输数据, 并使用高性能网络IO技术处理网络连接, 在语言层通过序列化+反射/预注册的形式调用接口.
Kitex 支持 Thrift 和 Proto3 两种IDL, 通过脚手架的形式根据IDL生成定义代码, 下面以一个简单的例子来演示如何使用
首先编写 Thrift 接口
namespace go api
struct NameRequest {
}
struct NameResponse {
1: string message
}
service NameService {
NameResponse name(1: NameRequest req)
}
然后运行编译命令(需要安装过kitex和thrift-go)
kitex -module github.com/cloudwego/kitex-examples -service name my.thrift
空项目第一次运行该命令会生成脚手架代码, 项目结构如下
├── build.sh
├── handler.go
├── kitex_gen
│ └── api
│ ├── k-consts.go
│ ├── k-my.go
│ ├── my.go
│ └── nameservice
│ ├── client.go
│ ├── invoker.go
│ ├── nameservice.go
│ └── server.go
├── kitex.yaml
├── main.go
├── my.thrift
└── script
└── bootstrap.sh
build.sh为构建脚本, bootstrap.sh为服务端运行脚本, kitex.yaml为配置文件 header.go 和 main.go 为 服务端RPC入口与主函数. kitex_gen 包下为IDL编译生成的文件,
我们需要在handler.go中实现接口, 并编写客户端代码
//handler.go
// Name implements the NameServiceImpl interface.
func (s *NameServiceImpl) Name(ctx context.Context, req *api.NameRequest) (resp *api.NameResponse, err error) {
resp = &api.NameResponse{Message: "xxrl"}
return resp, nil
}
//client/main.go
package main
import (
"context"
"log"
"time"
"github.com/cloudwego/kitex-examples/mytest/kitex_gen/api"
"github.com/cloudwego/kitex-examples/mytest/kitex_gen/api/nameservice"
"github.com/cloudwego/kitex/client"
)
func main() {
client, err := nameservice.NewClient("nameservice", client.WithHostPorts("0.0.0.0:8888"))
if err != nil {
log.Fatal(err)
}
for {
req := &api.NameRequest{}
resp, err := client.Name(context.Background(), req)
if err != nil {
log.Fatal(err)
}
log.Println(resp)
time.Sleep(time.Second)
}
}
通过sh build.sh sh output/bootstrap.sh 或go run .运行服务端
cd client; go run .运行客户端就可以看到结果了
Hertz
Hertz是Golang的微服务HTTP框架, 在设计之初就参考了fasthttp, gin, echo等框架, 吸取了它们的优点, 具有充分的后发者优势
使用Hertz框架可以使用脚手架hz生成, 也可以直接添加依赖使用
一个基本的http server实例如下
package main
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/common/utils"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
func main() {
h := server.Default(server.WithHostPorts("127.0.0.1:8081"))
h.GET("/ping", func(c context.Context, ctx *app.RequestContext) {
ctx.JSON(consts.StatusOK, utils.H{"ping": "pong"})
})
h.Spin()
}
首先指定配置创建server实例, 之后注册路由与对应的http处理函数, 最后调用Spin启动服务
注册路由, 路由组, 及路由参数, 参数绑定, 校验
v1 := h.Group("/v1")
{
v1.GET("/hertz/:version", func(ctx contex.Contex, c *app.RequestContext) {
version := c.Param("version")
c.String(consts.StatusOK, "Hello %s", version)
})
}
支持自定义中间件拦截请求
func MyMiddleware() app.HandleFunc {
return func(ctx context.Context, c *app.RequestContext) {
// pre-handle
c.Next(ctx)
// post-handle
}
}
func main() {
h.Use(MyMiddleware())
}
更多文档可以访问CloudWeGo, 及对应的 cloudwego/hertz-examples: Examples for Hertz. (github.com), cloudwego/kitex-examples: Examples for Kitex. (github.com) 示例项目找到高阶用法.