6.5 hertZ概览 #
一、hert架构设计 #
官方文档: https://www.cloudwego.io/zh/docs/hertz/
开源地址: https://github.com/cloudwego/hertz/blob/develop/README_cn.md
Hertz [həːts,即物理学家赫兹] 是字节跳动开源的 Go 微服务 HTTP 框架,在设计之初参考了其他开源框架 gin(公司内部二次开发的ginx)、 fasthttp、 echo 的优势, 并结合字节跳动内部的需求,使其具有高易用性、高性能、高扩展性等特点,目前在字节跳动内部已广泛使用。 如今越来越多的微服务选择使用 Golang,如果对微服务性能有要求,又希望框架能够充分满足内部的可定制化需求,Hertz 会是一个不错的选择。
框架特点 #
- 高易用性:在开发过程中,快速写出来正确的代码往往是更重要的。因此,在 Hertz 在迭代过程中,积极听取用户意见,持续打磨框架,希望为用户提供一个更好的使用体验,帮助用户更快的写出正确的代码。
- 高性能:Hertz 默认使用自研的高性能网络库 Netpoll,在一些特殊场景相较于 go net,Hertz 在 QPS、时延上均具有一定优势。关于性能数据,可参考下图 Echo 数据。
四个框架的对比:
三个框架的对比:
关于详细的性能数据,可参考 https://github.com/cloudwego/hertz-benchmark。
- **高扩展性:**Hertz 采用了分层设计,提供了较多的接口以及默认的扩展实现,用户也可以自行扩展。同时得益于框架的分层设计,框架的扩展性也会大很多。目前仅将稳定的能力开源给社区,更多的规划参考 RoadMap。
- **多协议支持:**Hertz 框架原生提供 HTTP1.1、ALPN 协议支持。除此之外,由于分层设计,Hertz 甚至支持自定义构建协议解析逻辑,以满足协议层扩展的任意需求。
- **网络层切换能力:**Hertz 实现了 Netpoll 和 Golang 原生网络库 间按需切换能力,用户可以针对不同的场景选择合适的网络库,同时也支持以插件的方式为 Hertz 扩展网络库实现。
hz工具 #
代码结构
|
|
hz client:
|
|
安装环境:
- GO安装最新版本;
- 确保
GOPATH
环境变量已经被正确地定义(例如export GOPATH=~/go
)并且将$GOPATH/bin
添加到PATH
环境变量之中(例如export PATH=$GOPATH/bin:$PATH
);请勿将GOPATH
设置为当前用户没有读写权限的目录。 - 设置国内代理:go env -w GOPROXY=https://goproxy.cn
- goland 安装 Thrift Support 插件;
- 安装命令行工具 hz(代码自动生成工具):
- hz 是 Hertz 框架提供的一个用于生成代码的命令行工具,可以用于生成 Hertz 项目的脚手架。
- 安装 hz:
go install github.com/cloudwego/hertz/cmd/hz@latest
- 更多 hz 使用方法可参考: hz
二、hertZ-开发流程 #
Step1:编写thrift IDL 接口定义 #
- 创建项目文件夹:
mkdir hertz_demo
cd hertz_demo
- 创建
hello.thrift
mkdir idl
;- touch
idl/hello.thrift
1 2 3 4 5 6 7 8 9 10 11
// idl/hello.thrift namespace go hello.example struct HelloReq { 1: string Name (api.query="name"); // 添加 api 注解为方便进行参数绑定 } struct HelloResp { 1: string RespBody; } service HelloService { HelloResp HelloMethod(1: HelloReq request) (api.get="/hello"); }
Step2:hz生成代码 #
- 生成代码: 详细参考
这里。 执行完毕后, 会在当前目录下生成 Hertz 项目的脚手架, 自带一个
ping
接口用于测试。1 2 3 4
# 在 GOPATH 外执行,需要指定 go mod 名 hz new -module hertz/demo -idl idl/hello.thrift # 整理 & 拉取依赖 go mod tidy
Step3:修改handler的业务逻辑 #
|
|
Step4:编译运行、接口测试 #
- 编译项目:
go build
- 运行项目并测试:
./demo
1 2
2022/05/17 21:47:09.626332 engine.go:567: [Debug] HERTZ: Method=GET absolutePath=/ping --> handlerName=main.main.func1 (num=2 handlers) 2022/05/17 21:47:09.629874 transport.go:84: [Info] HERTZ: HTTP server listening on address=[::]:8888
- 接下来,我们可以对接口进行测试:
1 2 3 4
curl http://127.0.0.1:8888/ping {"message":"pong"} curl "http://127.0.0.1:8888/hello?name=chow" {"RespBody":"Hello chow!"}
Step5:迭代需求 (相同)1. 更新 thrift IDL 接口定义 #
|
|
hz生成代码
切换到执行 new 命令的目录,更新修改后的 thrift idl:
hz update -idl idl/hello.thrift
- 在 biz/handler/hello/example/hello_service.go 新增了新的方法
- 在 biz/handler/hello/example 下新增了文件 new_service.go 以及对应的 “NewMethod” 方法
修改handler的业务逻辑
修改 “OtherMethod” 接口的业务逻辑:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// OtherMethod . // @router /other [POST] func OtherMethod(ctx context.Context, c *app.RequestContext) { var err error // example.OtherReq 对应的 model 文件也会重新生成 var req example.OtherReq err = c.BindAndValidate(&req) if err != nil { c.String(400, err.Error()) return } resp := new(example.OtherResp) // 增加的逻辑 resp.Resp = "Other method: " + req.Other c.JSON(200, resp) }
编译运行、接口测试
编译项目:
go build
运行:./demo
接口测试:
1 2 3 4 5 6
curl --location --request POST 'http://127.0.0.1:8888/other' \ --header 'Content-Type: application/json' \ --data-raw '{ "Other": "other method" }' 返回: {"Resp":"Other method: other method"}
path不存在时,返回:404 page not found