Kitex | 青训营笔记

219 阅读4分钟

这是我参与「第五届青训营」笔记创作活动的第十四天。

一:本堂课的重点内容

kitex的基础介绍

二:详细知识点如下

1)介绍

kitex是字节跳动内部使用的Golang微服务RPC框架。具有高性能、强可扩展的特点。

kitex使用字节跳动自研的Netpoll网络库,比go net的性能更高,这也是kitex高性能的一个原因。采用了模块化的设计,在整个服务框架的基础上,将可以替换的内容全部抽象为扩展接口并提供了默认的实现。一般情况下,用户使用默认实现即可,必要的话,用户可以按照自己的需要来自行实现扩展接口。 Kitex 是一个 RPC 框架,既然是 RPC,底层就需要两大功能:

Serialization 序列化 Transport 传输

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

2)安装代码生成工具

image.png

3)为什么要使用 IDL

如果我们要进行 RPC,就需要知道对方的接口是什么,需要传什么参数,同时也需要知道返回值是什么样的,就好比两个人之间交流,需要保证在说的是同一个语言、同一件事。这时候,就需要通过 IDL 来约定双方的协议,就像在写代码的时候需要调用某个函数,我们需要知道函数签名一样。

编写IDL文件
syntax = "proto3";

package echo;

option go_package = "api";

message Request {
    string message = 1;
}

message Response {
    string message = 1;
}

service Echo {
    rpc Echo(Request) returns (Response);
}
生成服务代码
kitex -module echo -service echo echo.proto
  • -module表示生成项目的go module名
  • -service表示生成一个服务端项目,后面紧跟的echo是服务的名字
  • 最后的echo.proto就是使用的IDL的文件

生成的项目结构如下所示

image.png

可以看到proto生成的代码在kitex_gen目录下,并且路径与go_package中的一致。

顺便提一下,在编写proto文件的时候要非常注意,go_package的路径最终一定要在kitex_gen路径下,否则运行上面的命令生成代码会报错
就是说:

  • 如果是非绝对路径也不是以.开头的路径,那么默认就是生成在kitex_gen目录下
  • 绝对路径要保证路径为 {当前项目根路径}/kitex_gen/xxx/xxx
  • 不要使用.开头的路径写法

如果使用的protoc的版本较新的话,会要求go_package一定要包含.或者/,所以为了避免出错,也为了简单,最好直接使用api/xxx类型格式的路径。

4)基本使用

服务默认监听8888端口

image.png

5)编写客户端

有了服务端后,接下来就让我们编写一个客户端用于调用刚刚运行起来的服务端。

  • 首先,同样的,先创建一个目录用于存放我们的客户端代码:

$ mkdir client

  • 进入目录:

$ cd client

创建一个 main.go 文件,然后就开始编写客户端代码了。

创建 client

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

import "example/kitex_gen/api/echo"
import "github.com/cloudwego/kitex/client"
...
c, err := echo.NewClient("example", client.WithHostPorts("0.0.0.0:8888"))
if err != nil {
  log.Fatal(err)
}

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

发起调用
import "example/kitex_gen/api"
...
req := &api.Request{Message: "my request"}
resp, err := c.Echo(context.Background(), req, callopt.WithRPCTimeout(3*time.Second))
if err != nil {
  log.Fatal(err)
}
log.Println(resp)

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

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

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

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

6)服务注册

image.png

三、课后个人总结

在Kitex的学习过程中,使用Kitex从零构建了自己的服务,只要定义好IDL(接口描述语言),按照Kitex提供的命令行规则,就可以生成支持ThriftProtobuf的客户端和服务端相关的脚手架代码,使得我们可以直接着手编写服务端的响应实现和客户端的请求发起逻辑。

四、引用参考

www.w3cschool.cn/kitex/kitex…

www.dianjilingqu.com/620041.html