Gorm、KiteX、Hertz框架(4)| 青训营笔记

137 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天

下面来看KiteX

KiteX没有做windows的支持,所以建议在linux下使用。

文档给出的kitex-example我这边没法用,一跑我的服务器直接炸了。(阿里云你行不行啊,动不动服务器就炸,连不上)

就从纯手工构建开始吧。kitex是一个rpc架构,如果你不知道rpc是什么可以先去了解一下。

rpc(remote process call)远程调用,从名称上就可以知道这个架构干啥的了。我们的目标是我们调用一个远程的函数和调用一个本地函数一样。

kitex可以使用protobuf和thrift来自动构建我们的代码(所以我的上一篇是将protobuf和thrift)。

kitex的使用需要两个go组件:

go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
go install github.com/cloudwego/thriftgo@latest

安装即可,注意GOPATH和PATH路径问题($GOPATH/bin要能被搜索)。

这里我们使用thrift来编写我们的IDL:

namespace go calculate

struct Request {
    1: string token,
    2: i64 lhs,
    3: i64 rhs
}

struct Response {
    1: byte status,
    2: i64 res
}

service CalculateService {
    Response Add(1: Request req)
    Response Sub(1: Request req)
    Response Mul(1: Request req)
}

写了一个简单计算器。

然后就可以使用kitex生成代码了。

kitex -module calculate -service calculate calculate.thrift

导出的代码结构如下:

.
├── build.sh
├── Calculate.thrift
├── go.mod
├── handler.go
├── kitex_gen
│   └── calculate
│       ├── Calculate.go
│       ├── calculateservice
│       │   ├── calculateservice.go
│       │   ├── client.go
│       │   ├── invoker.go
│       │   └── server.go
│       ├── k-Calculate.go
│       └── k-consts.go
├── kitex.yaml
├── main.go
└── script
    └── bootstrap.sh

这个Calculate.thrift是我之前写的thrift文件。

这时候我们的有些文件还是会报错的,因为我们依赖还没装,直接使用go mod tidy即可自动的拉取依赖。

kitex_gen下就是kitex主要的逻辑代码,我们生成的类都在其中。

handler.go是我们的业务逻辑实现的地方。

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

// Add implements the CalculateServiceImpl interface.
func (s *CalculateServiceImpl) Add(ctx context.Context, req *calculate.Request) (resp *calculate.Response, err error) {
	// TODO: Your code here...
	return
}

// Sub implements the CalculateServiceImpl interface.
func (s *CalculateServiceImpl) Sub(ctx context.Context, req *calculate.Request) (resp *calculate.Response, err error) {
	// TODO: Your code here...
	return
}

// Mul implements the CalculateServiceImpl interface.
func (s *CalculateServiceImpl) Mul(ctx context.Context, req *calculate.Request) (resp *calculate.Response, err error) {
	// TODO: Your code here...
	return
}

他已经把函数声明啥的都写好了,我们只需要在函数体里面添加上自己的逻辑即可(让我回想起了MFC)。

接下来我们来实现这几个函数,写上简单的功能。

// Add implements the CalculateServiceImpl interface.
func (s *CalculateServiceImpl) Add(ctx context.Context, req *calculate.Request) (resp *calculate.Response, err error) {
	return &calculate.Response{Status: 0, Res: req.Lhs + req.Rhs}, nil
}

// Sub implements the CalculateServiceImpl interface.
func (s *CalculateServiceImpl) Sub(ctx context.Context, req *calculate.Request) (resp *calculate.Response, err error) {
	return &calculate.Response{Status: 0, Res: req.Lhs - req.Rhs}, nil
}

// Mul implements the CalculateServiceImpl interface.
func (s *CalculateServiceImpl) Mul(ctx context.Context, req *calculate.Request) (resp *calculate.Response, err error) {
	return &calculate.Response{Status: 0, Res: req.Lhs * req.Rhs}, nil
}

完成后,使用kitex生成的shell脚本进行build。

这时候,你会发现,报错啦。一片红。

这个问题其实在上一篇的Thrift中提及到。thrift在0.14版本开始,对api的参数进行了修改,会默认带上一个context参数。然而我们生成的代码是没有这个的。所以报错了。解决方法:www.cloudwego.io/zh/docs/kit…

将我们使用的thrift库指定到0.13版本即可。

go get github.com/apache/thrift@v0.13.0

脚本会生成一个output文件夹,下面包含我们的build出的可执行文件和一个boost脚本。运行这个boost脚本我们就可以启动我们的服务端了。

wsl-kali@mylaptop:~/GoProject/kitex$ ./output/bootstrap.sh 
2023/01/30 22:37:02.288521 server.go:81: [Info] KITEX: server listen at addr=[::]:8888

接下来我们来编写client。

package main

import (
	"calculate/kitex_gen/calculate"
	"calculate/kitex_gen/calculate/calculateservice"
	"context"
	"fmt"
	"github.com/cloudwego/kitex/client"
)

func main() {
	c, err := calculateservice.NewClient("calculate", client.WithHostPorts("0.0.0.0:8888"))
	if err != nil {
		panic(err)
	}

	req := &calculate.Request{Token: "success", Lhs: 20, Rhs: 30}
	response, err := c.Add(context.Background(), req)
	if err != nil {
		panic(err)
	}
	fmt.Println(response)
}

不同项目之间的本地包依赖挺麻烦的,这里就直接放在同项目下了。

首先我们导入了两个包一个是calculate一个calculateservice。这个其实一个是calculate结构相关定义以及接口定义的地方。而calculateservice是我在thrift中定义的服务名。

我们从服务包中创建一个新的客户端。然后通过这个client来进行远程调用。如果你的调用不需要参数的话,你可以不写calculate包。

...
├── kitex_gen
│   └── calculate
│       ├── calculate.go
│       ├── calculateservice
│       │   ├── calculateservice.go
│       │   ├── client.go
│       │   ├── invoker.go
│       │   └── server.go
│       ├── k-calculate.go
│       └── k-consts.go
...

如果你不知道你的包叫啥名字,你可以在kitex_gen下面的文件中找到,例如这个calculate.go,package就是calculate。而calculateservice下的calculateservice.go显示的package为calculateservice。(目录名一般来说就是包名)

下面执行即可进行一次调用:

wsl-kali@mylaptop:~/GoProject/kitex$ go run client/client.go 
Response({Status:0 Res:50})