概览
大家好!今天我想向大家介绍一款备受关注的Go语言框架三件套之——Kitex。作为一个高性能、轻量级的RPC框架,Kitex在Go社区中拥有着广泛的用户群体和良好的口碑。下面就让我们来一起深入剖析Kitex框架的特点和优势。
Thrift 简介
Thrift 本身是一软件框架(远程过程调用框架),用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引 擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。同时,作为 IDL(接口定义语言 Interface Definition Language),允许你定义一个简单的定义文件中的数据类型和服务接口,以作为输入文件,编译器生成代码用来方便地生成 RPC 客户端和服务器通信的无缝跨编程语言。
Protobuf 简介
Protobuf 全称是 Google Protocol Buffer,是一种高效轻便的结构化数据存储方式,用于数据的通信协议、数据存储等。相对比 XML 来说,其特点:
- 语言无关,平台无关
- 高效
- 扩展性、兼容性更强
基于 IDL 的 KiteX 实践
在 RPC 框架中,我们知道,服务端与客户端通信的前提是远程通信,但这种通信又存在一种关联,那就是通过一套相关的协议(消息、通信、传输等)来规范,但客户端又不用关心底层的技术实现,只要定义好了这种通信方式即可。
在 KiteX 中,也提供了一种生成代码的命令行工具:kitex,目前支持 thrift、protobuf 等 IDL,并且支持生成一个服务端项目的骨架。
安装命令行工具
环境
- 如果您之前未搭建 Golang 开发环境, 可以参考 Golang 安装
- 推荐使用最新版本的 Golang,我们保证最新三个正式版本的兼容性(现在 >= v1.16)。
- 确保打开 go mod 支持 (Golang >= 1.15 时,默认开启)
- kitex 暂时没有针对 Windows 做支持,如果本地开发环境是 Windows 建议使用 WSL2
安装
- 确保 GOPATH 环境变量已经被正确地定义(例如 export GOPATH=~/go)并且将 GOPATH/bin:$PATH);请勿将 GOPATH 设置为当前用户没有读写权限的目录
- 安装 kitex:go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
- 安装 thriftgo:go install github.com/cloudwego/thriftgo@latest
安装成功后,执行 kitex --version 可以看到如下信息:
$ kitex --version
v0.4.2
如果在安装阶段发生问题,可能主要是由于对 Golang 的不当使用造成的,需要逐一排查。
下面,让我们以使用thrift作为示例来说明基于IDL的Kitex实践:
首先,你需要安装Kitex的命令行工具,可以通过以下命令来完成,
在终端中运行以下命令来安装 Kitex 的命令行工具:
go get github.com/cloudwego/kitex/tools/kitex
定义你的 IDL 文件,如 example.thrift。
在终端中运行以下命令来生成对应的 Go 代码:
kitex idl example.thrift
该命令会根据thrift定义文件生成Go代码并将其放置在当前目录的"gen"文件夹中。
继续在终端中创建服务端的主文件 server.go:
package main
import (
"context"
"fmt"
"net"
"github.com/cloudwego/kitex/server"
"github.com/cloudwego/kitex/transport"
"github.com/project/example/gen/api"
)
type UserServiceImpl struct{}
func (s *UserServiceImpl) GetUser(ctx context.Context, id int32) (*api.User, error) {
// 在这里实现具体的业务逻辑
fmt.Println("处理 GetUser 请求,用户ID为:", id)
return &api.User{
Id: id,
Name: "testUser",
}, nil
}
func main() {
userService := &UserServiceImpl{}
userServiceServer := api.NewUserServiceServer(userService)
// 创建并配置服务端的处理器
h := server.NewServer(server.WithService(userServiceServer))
// 创建并配置传输层
lis, err := net.Listen("tcp", ":8888")
if err != nil {
fmt.Println("Failed to create listener:", err)
return
}
transOpt := transport.WithListener(lis)
// 启动服务
h.Run(transOpt)
}
创建一个名为 client.go 的文件,实现客户端的调用代码:
package main
import (
"context"
"fmt"
"net"
"github.com/cloudwego/kitex/client"
"github.com/cloudwego/kitex/transport"
"github.com/project/example/gen/api"
)
func main() {
trans, err := transport.NewClientTransport(":8888")
if err != nil {
fmt.Println("Failed to create transport:", err)
return
}
// 创建客户端
userServiceClient := api.NewUserServiceClient(client.NewClient(trans))
// 创建上下文和请求参数
ctx := context.TODO() req := &api.GetUserInput{ Id: 123, }
// 调用服务端接口
resp, err := userServiceClient.GetUser(ctx, req)
if err != nil {
fmt.Println("Failed to call GetUser:", err)
return
} fmt.Println(
"GetUser 返回结果:", resp)
}
这是一个使用Kitex(一个Go语言微服务框架)编写的客户端代码示例,用于调用一个名为UserService的服务的GetUser方法来获取用户信息。
这里是代码的详细解释:
- 导入了所需的包,其中"github.com/cloudwego/kitex/client"和"github.com/cloudwego/kitex/transport"是Kitex的客户端和传输层的包。
- main函数是程序的入口。
- 创建一个客户端传输对象(trans)来与服务端进行通信。
- 使用api.NewUserServiceClient函数通过客户端传输对象创建一个UserService的客户端(userServiceClient)。
- 创建上下文对象(ctx)和请求参数对象(req),这里请求参数是GetUserInput的一个实例,包含一个Id字段。
- 调用userServiceClient的GetUser方法,传入上下文和请求参数。该方法会返回一个响应对象(resp)和可能的错误(err)。
- 检查调用过程中是否出现错误,如果有错误则打印错误信息并退出。
- 如果没有错误,打印获取到的用户信息(resp)。
需要注意的是,此示例使用默认的本地传输(可通过":8888"指定端口),以便在同一台机器上测试。实际情况中,你需要根据实际的服务端地址和端口进行调整。还需要注意替换api.GetUserInput和api.UserServiceClient为实际的接口和客户端类型。
在 VSCode 中打开项目目录。 使用终端运行 server.go 文件来启动服务端:
go run server.go
再次使用终端运行 client.go 文件来调用客户端:
go run client.go
通过以上步骤,你可以在 VSCode 中完成基于 IDL 的 Kitex 实践,并通过服务端和客户端的代码实现你的业务逻辑。
在 vscode 中进行基于 IDL 的 Kitex 实践,你还可以使用 Go 扩展提供的功能,如代码自动补全、语法高亮、跳转到定义等,来提升开发效率。
通过在 vscode 中进行基于 IDL 的 Kitex 实践,你可以方便地使用命令行工具生成代码,并在集成开发环境中进行代码编写和调试,更加高效地开发和维护 RPC 服务。