这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天
前言
本文主要内容为Go语言HTTP框架——Hertz。
Hertz是字节内部开源的http框架,参考了其他开源框架的优势,结合字节跳动内部的需求,具有高易用性、高性能、高扩展性等特点。
基础使用
安装Hertz
安装Hertz需要确保电脑已经正确安装了Go,并且Go的版本要>=1.15。
执行以下命令进行安装Hertz:
go install github.com/cloudwego/hertz/cmd/hz@latest
安装后进行验证,输入以下命令:
hz -v
如果能正确输出版本信息,如下,就说明已经安装好了。
hz version v0.5.2
生成示例代码
可以使用hz命令直接生成示例代码,步骤如下:
- 在当前目录下创建
hertz文件夹,进入该目录中 - 执行生成代码命令
hz new或者使用hz new -module example - 执行命名
go mod tidy整理、拉取依赖
生成代码目录如下:
打开main.go文件,添加以下代码
到此,一个简单的http服务就完成了,现在可以编译并启动Server了。
go run main.go
运行命令,成功启动后,输出以下信息:
我们可以看到,服务已经正常启动,并且默认端口号为8888,打开浏览器输入访问地址
http://127.0.0.1:8888/ping
访问后,可以看到浏览器输出一个json,内容如下:
{"message":"pong"}
Hertz路由
Hertz提供了多种路由规则,路由的优先级为:静态路由 > 命名路由 > 通配路由。
静态路由
Hertz提供了GET、POST、PUT、DELETE、ANY等方法用于注册路由。
路由组
Hertz提供了路由组(Group)的能力,用于支持路由分组的功能。
参数路由
Hertz 支持使用 :name 这样的命名参数设置路由,并且命名参数只匹配单个路径段。
如果我们设置/hertz/:version路由,匹配情况如下:
| 路径 | 是否匹配 |
|---|---|
| /hertz/v1 | 匹配 |
| /hertz/v2 | 匹配 |
| /hertz/v1/detail | 不匹配 |
| /hertz/ | 不匹配 |
通过使用 RequestContext.Param 方法,我们可以获取路由中携带的参数。
h.GET("/hertz/:version", func(ctx context.Context, c *app.RequestContext) {
version := c.Param("version")
c.String(consts.StatusOK, "Hello %s", version)
})
通配路由
Hertz 支持使用 *path 这样的通配参数设置路由,并且通配参数会匹配所有内容。
如果我们设置/hertz/*path路由,匹配情况如下
| 路径 | 是否匹配 |
|---|---|
| /hertz/v1 | 匹配 |
| /hertz/v1/detail | 匹配 |
| /hertz/ | 匹配 |
通过使用 RequestContext.Param 方法,我们可以获取路由中携带的参数。
h.GET("/hertz/:version/*action", func(ctx context.Context, c *app.RequestContext) {
version := c.Param("version")
action := c.Param("action")
message := version + " is " + action
c.String(consts.StatusOK, message)
})
参数绑定
Hertz提供了 Bind、Validate、BindAndValidate 函数用于进行参数绑定校验。
绑定的作用是把http请求的参数封装到定义的结构体里面方便开发使用,Hertz使用的是tag的方式进行绑定的。
| Tag | 说明 |
|---|---|
| path | 绑定 url 上的路径参数,相当于 hertz 路由 :param 或 *param 中拿到的参数 |
| form | 绑定请求的 body 内容 |
| query | 绑定请求的 query 参数 |
| header | 绑定请求的 header 参数 |
| json | 绑定 json 参数 |
| vd | 参数校验 |
绑定使用的是BindAndValidate方法,使用方法如下:
Hertz Client
Hertz提供了 Http Client 用于帮助用户发送 Http 请求,可以在代码的逻辑中请求第三方服务。
例如,使用GET发送一个Http请求:
func Get() {
c, err := client.NewClient()
if err != nil {
return
}
status, body, _ := c.Get(context.Background(), nil, "http://www.example.com")
fmt.Printf("status=%v body=%v\n", status, string(body))
}
使用POST发送一个Http请求:
func Post() {
c, err := client.NewClient()
if err != nil {
return
}
var postArgs protocol.Args
postArgs.Set("arg", "a") // 发送参数
status, body, _ := c.Post(context.Background(), nil, "http://www.example.com", &postArgs)
fmt.Printf("status=%v body=%v\n", status, string(body))
}
代码生成
Hertz提供了代码生成工具 Hz,hz 是 Hertz 框架提供的一个用于生成代码的命令行工具,hz 可以基于 thrift 和 protobuf 的 IDL 生成 Hertz 项目的脚手架。
先定义一个IDL文件,如hello.thrift
namespace go hello.example
struct HelloReq {
// 添加 api 注解为方便进行参数绑定
1: string Name (api.query="name");
}
struct HelloResp {
1: string RespBody;
}
service HelloService {
HelloResp HelloMethod(1: HelloReq request) (api.get="/hello");
}
执行命令生成代码,并整理依赖:
hz new -idl hello.thrift
go mod tidy
生成的文件结构如下:
Hertz性能
Hertz是一个高性能Web框架,之所以高性能是因为以下几点:
- 使用高性能网络库
Netpoll Json编解码Sonic,Sonic是一个高性能Json编解码库- 使用
sync.Pool复用对象协议层数据解析优化
Hertz生态
Hertz拥有非常丰富的扩展生态:
Http2扩展opentelemetry扩展- 国际化扩展
- 反向代理扩展
JWT鉴权扩展Websocket扩展- 丰富的代码示例
引用
字节内部视频——Go框架三件套详解(Web/RPC/ORM)