Go框架三件套详解之Kitex | 青训营

58 阅读6分钟

Kitex框架的使用入门

Kitex是一个高性能、可扩展的RPC框架,它基于Thrift和Protobuf协议,提供了服务治理、链路追踪、负载均衡等功能。Kitex在字节内部被广泛使用,并且已经开源给社区。 本文是基于字节课程《Go 框架三件套详解(Web/RPC/ORM)》的实践记录之一,下面将根据课程内容,并结合实际例子进行Kitex框架使用的介绍。

安装Kitex代码生成工具

Kitex目前对Windows系统的支持还不太完善,原因是Kitex虽然是能在Windows系统上运行的,但是Kitex代码生成工具对Windows系统的支持还不完善,所以建议大家还是在Linux环境下进行开发。笔者用的是WSL2,Ubuntu 18.04LTS发行版。

可以使用以下命令来安装或者更新 kitex:

go install github.com/cloudwego/kitex/tool/cmd/kitex

完成后,查看kitex版本,验证是否安装成功。

kitex -version

如果出现 command not found 错误,可能是因为没有把 $GOPATH/bin 加入到 $PATH 中。

接着通过以下指令安装thriftgo:

go install github.com/cloudwego/thriftgo@latest

定义和编写IDL

在微服务架构中,各个服务之间是通过RPC,即Remote Procedure Call(远程过程调用)来进行通信的,既然是调用,那么我们就需要知道对方提供给我们的调用接口、传递的参数以及调用的返回值结果。因此,我们需要先编写IDL文件来约定双方的协议,就像在写代码的时候需要调用某个函数,我们需要知道函数签名。

Kitex 框架及命令行工具,默认支持 thrift 和 proto3 两种 IDL,对应的 Kitex 支持 thrift 和 protobuf 两种序列化协议。 传输上 Kitex 使用扩展的 thrift 作为底层的传输协议(注:thrift 既是 IDL 格式,同时也是序列化协议和传输协议)。IDL 全称是 Interface Definition Language,接口定义语言。

在本文中,笔者使用Proto3协议进行IDL的编写,下面将以Relation模块中的几个接口为例子进行项目实践。

业务场景描述

根据官方项目文档,我们需要定义Follow、UnFollow(由FollowAction拆分而成)、ListFollow、ListFollower和ListFriend这几个接口,分别完成关注、取关、获取所有关注者、粉丝和朋友这些功能。此外,考虑到在实际业务场景中,我们常常需要获取一个用户的粉丝数、关注数以及自己是否关注了这个用户,我们还需要定义一个接口GetFollowInfo来实现,官方文档中已经提供了以上几个接口的Proto2协议定义,现在我们以GetFollowInfo为例,首先是定义一些结构体。

定义非请求和响应的结构体

首先定义非请求和响应的结构体。此外,为了使IDL文件能展示得更清晰,建议把这些结构体放在前面,例如Status、UserInfo和FollowInfo等。Status是状态码,放在响应中,用以判断调用是否成功。UserInfo为用户信息,定义在官方文档里,这里不再介绍。FollowInfo为关注信息,包含一个用户的user_id、关注数、粉丝数以及自己是否是查询目标的粉丝,即是否关注。定义如下:

message FollowInfo {
  int64 user_id = 1;
  int64 follow_count = 2;
  int64 follower_count = 3;
  bool is_follow = 4;
}

定义请求和响应结构体

在relation模块中,我们提供了一个接口GetFollowInfo,用以获取关注信息,用户传入自己的ID,并传入一组用户ID,模块将返回给该用户这些查询目标用户的关注数、粉丝数和是否关注等信息,Proto3定义如下:

message GetFollowInfoReq {
  int64 user_id = 1;     // 用户id
  repeated int64 to_user_id_list = 2; // 要查询的用户的ID列表
}

定义模块RPC服务

我们已经定义了GetFollowInfo的请求和响应结构体,并且假设我们也已经完成了官方文档中的关注、取消关注、获取关注者、获取粉丝和获取朋友等接口。现在我们需要完成最后一步,定义RPC服务即可完成IDL文件的编写。RelationService的定义如下:

service RelationService {
  rpc GetFollowInfo(GetFollowInfoReq) returns (GetFollowInfoRes);
  rpc Follow(FollowReq) returns (FollowRes);
  rpc Unfollow(UnfollowReq) returns (UnfollowRes);
  rpc ListFollow(ListFollowReq) returns (ListFollowRes);
  rpc ListFollower(ListFollowerReq) returns (ListFollowerRes);
  rpc ListFriend(ListFriendReq) returns (ListFriendRes);
}

将IDL文件编写完成后,保存,我们就可以使用Kitex代码生成工具生成相应代码了,执行如下命令即可

kitex -module {项目模块} -service relation relation-service.proto

Kitex基本使用

执行上面的命令之后,可以看到Kitex生成的代码,其中,生成了handler.go等文件,handler.go中是写业务逻辑的地方。如果业务逻辑比较简单,比如只需要几行就可以完成,那么可以把业务逻辑都直接写在里面,如果代码量多,业务复杂,那么可能需要进行一定的分层。还有一点,在Kitex中,服务是默认监听8888端口的。


// RelationServiceImpl implements the last service interface defined in the IDL.
type RelationServiceImpl struct {}

// GetFollow implements the RelationServiceImpl interface.
func (s *RelationServiceImpl) GetFollow(ctx context.Context, req *relation.GetFollowInfoReq) (resp *relation.GetFollowInfoRes, err error) {
  // TODO: Your code here...
  return
}

创建Client

首先让我们创建一个调用所需的 client

c, err := relation.NewClient("relation", client.WithHostPorts("0.0.0.0:8888"))
if err != nil {
  log.Fatal(err)
}

上述代码中,relation.NewClient 用于创建 client,其第一个参数为调用的 服务名,第二个参数为 options,用于传入参数, 此处的 client.WithHostPorts 用于指定服务端的地址。

发起调用

接下来让我们编写用于发起调用的代码:

req := &relation.GetFollowInfoReq{"当前用户id和查询的用户id列表"}
resp, err := c.GetFollowInfo(context.Background(), req, callopt.WithRPCTimeout(3*time.Second))
if err != nil {
  log.Fatal(err)
}
log.Println(resp)

上述代码中,我们首先创建了一个请求 req , 然后通过 c.GetFollowInfo 发起了调用。

其第一个参数为 context.Context,通过通常用其传递信息或者控制本次调用的一些行为。

其第二个参数为本次调用的请求。

其第三个参数为本次调用的 options ,Kitex 提供了一种 callopt 机制,顾名思义——调用参数 ,有别于创建 client 时传入的参数,这里传入的参数仅对此次生效。 此处的 callopt.WithRPCTimeout 用于指定此次调用的超时(通常不需要指定,此处仅作演示之用)。

到这里,如果你没有报错,并且获取了正确的返回结果,那么说明你已经学会了Kitex的基本使用了。

本文仅仅介绍了Relation模块中的GetFollowInfo接口,你也可以举一反三完成Relation模块中其他接口的编写,进一步实现Comment、Favorite等其他接口,最后再结合Gorm和Hertz框架完成整个项目。

总结

本文介绍了Kitex框架的使用入门,从Kitex的安装到Kitex实战,包含了编写定义IDL文件、生成代码、编写服务端和客户端以及进行一次调用的Kitex使用全流程,并且结合了此次青训营的抖音极简版项目进行讲解。

当然,本文讲解的层次较浅,并且笔者技术有限,如果需要学习Kitex框架的进阶用法和高级特性请参考官方文档:Kitex | CloudWeGo。如果文章中出现了明显错误也请读者们批评指正,感谢观看。