hertz_kitex实战 | 青训营

254 阅读4分钟

github.com/cloudwego/h… 项目地址

文件理解

一共有两个thrift文件,student_api和sutdent_management。对前者生成rpc和http框架,后者只负责rpc服务

  1. StudentApi这个HTTP服务仅定义了接口和数据结构,还需要一个后端RPC服务来实现真正的业务逻辑。
  2. 典型做法是StudentApi只做转发作用,接收HTTP请求后,再调用后端RPC服务StudentManagement去实际执行查询、插入等逻辑。
  3. 所以必须要有StudentManagement这个RPC服务存在,由它来实现StudentApi声明的具体业务功能。
  4. 而StudentApi主要起到一个适配的作用,把HTTP请求转换成对后端RPC服务的调用。

可以通过这个流程来理解:

用户 -> HTTP请求 -> StudentApi -> RPC请求 -> StudentManagement ^⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀^
适配转发

所以,仅有定义HTTP接口的StudentApi是不够的,还需要有StudentManagement作为后端RPC服务来实现业务逻辑,这两者必须配合使用。

从这个Thrift定义看,有两个namespace:

  • api: 定义了面向用户的API接口
  • student.management: 定义了内部的student管理接口

使用两个namespace的原因可能有:

  1. 将外部接口和内部接口分离

api中定义的是外部访问的接口规范,包含了接口的文档、参数绑定等信息。

student.management是内部实际业务接口。

  1. 解耦外部API和内部实现

外部api可以看做是一个适配层。内部服务实现可以独立变更,不会影响对外API。

  1. 外部API稳定,内部接口可变

外部api一旦确定就不太变化,但内部接口可能需要迭代。

  1. 代码分层

不同namespace可以生成到不同目录或package中,便于代码组织。

  1. 安全隔离

外部api和内部服务对外和内部网络可能需要隔离。

总之,这种设计是为了将外部接口和内部实现解耦,提高内部变更的灵活性,也使得外部api更稳定。

如果接口之间不需要隔离,也可以合并到一个文件中,通过不同service来区分。

![W8JI94JVN64EC%[SQDS8$G.png

代码分析

  1. Hertz 代码实现了 HTTP 路由映射,queryStudent 映射到 GET /student/query,insertStudent映射到 POST /student/insert。
  2. 接收 HTTP 请求后,会做参数绑定和验证。
  3. 然后使用 kitex 生成的 RPC client 去调用后端的 StudentManagement 服务。
  4. 并把 RPC 返回结果组装成 HTTP 响应返回。
  5. 如果 RPC 调用失败,会返回错误信息。

所以这个文件主要做的是:

  • Hertz 提供了 HTTP 服务框架。
  • 使用 kitex 的 RPC client 调用后端服务。
  • 组装和适配请求/响应格式。
  • 处理错误情况。

这实现了典型的 Thrift HTTP+RPC 分层架构,可以复用 StudentManagement 的 RPC 服务实现。

HTTP 服务端只负责协议适配,不处理业务。业务由 RPC 服务实现,二者解耦。

利用 Hertz 和 kitex 可以很好地支持这种架构。

树状结构

image.png

第一个包括kitex生成的kitex_gen 和 hertz生成的biz,后者只有kitex_gen

hertz代码结构

image.png

www.cloudwego.io/zh/docs/her…

结合实际

路由映射

image.png

image.png

路由注册

image.png

image.png

中间件

image.png

image.png

handler

image.png

image.png

image.png

这是主函数的代码,用于启动Hertz框架搭建的HTTP服务器。

主要包含以下部分:

  1. 引入Hertz相关包
go

Copy code

"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/app/server"
  1. 创建Hertz实例
go

Copy code

h := server.Default()

使用Default()函数创建实例。

  1. 配置Hertz服务
go

Copy code

server.WithHostPorts("127.0.0.1:8080")

设置监听的地址和端口。

  1. 注册全局中间件
go

Copy code

h.Use(middleware)

这里实现了一个打印日志的简单中间件。

  1. 注册路由
go

Copy code

register(h)

调用之前实现的register函数注册所有的路由。

  1. 启动服务
go

Copy code

h.Spin()

最后调用Spin()启动Hertz服务器。

所以这个文件创建了一个Hertz服务器实例,配置了端口,注册中间件和路由,然后启动服务。

我们的业务代码可以主要编写在register里面注册的处理函数中。

这样可以基于Hertz框架快速创建一个HTTP服务。

kitex--rpc部分

image.png

image.png

image.png

如何通过http框架调用rpc客户端,再通过客户端调用rpc服务器

image.png