这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天,本文介绍了三个 Go 开发框架 GORM,Kitex,Hertz之一 Kitex 的基本使用方法,关于kitex的介绍在上文.
上文(第一篇)地址:juejin.cn/post/719148…
一.相关信息
-
Kitex目前对Windows的支持不完善,Kitex代码可以在windows上跑,代码生产工具运行在windows上可能有bug,使用windows的可以使用虚拟机或者WSL2.
-
安装代码生成工具
- 安装 kitex:
go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
- 安装 thriftgo
go install github.com/cloudwego/thriftgo@latest
安装成功后可以使用
kitex --version
,显示出版本号就是安装成功了 - 安装 kitex:
1.定义IDL
- 接口描述语言(Interface description language,缩写IDL),通过一种独立于编程语言的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以相互通信交流IDL通常用于远程调用软件。
- Kitex 默认支持
thrift
和proto3
两种 IDL,而在底层传输上,Kitex 使用扩展的thrift
作为底层的传输协议。 - 创建一个名为
echo.thrift
的文件,将下列代码添加入内
namespace go api
struct Request {
1 : string message
}
struct Response {
1 : string message
}
service Echo {
Response echo(1 : Request req)
}
- 使用IDL定义服务与接口
- 如果我们要进行RPC,就需要知道对方的接口是什么,需要传什么参数,同时也需要知道返回指是什么样的.这时候,就需要通过IDL来约定双方的协议,就像在写代码的时候需要调用某个函数,我们需要知道函数签名一样.
- Thrift : thrift.apache.org/docs/idl
- Proto3 : developers.google.com/protocol-bu… ( 如果已经废弃就protobuf.dev/ )
2.Kitex生成代码
使用kitex -module [example] -service [example] echo.thrift
生成服务端代码
第一个example为go项目的名称,第二个example为生成的RUN_NAME的名称.
- build.sh : 构建脚本,将代码变成一个可执行的二进制文件
- kitex_gen : IDL内容相关的生成代码,主要是基础的Server/Client代码
- kitex的编解码的优化会在里面
- main.go : 程序入口
- handler.go : 用户在该文件里实现IDL service 定义的方法
项目/kitex_gen/api/echo文件中函数参数错误
出现上述情况需要首先查看是否为最新版本,执行下面命令使用go mod进行依赖管理
go get github.com/cloudwego/kitex@latest
go mod tidy
如果发现还是爆红就输入下面命令
go mod edit -droprequire=github.com/apache/thrift/lib/go/thrift
go mod edit -replace=github.com/apache/thrift=github.com/apache/thrift@v0.13.0
二.Kitex的基础使用
1.服务器默认监听8888端口
package main
import (
"context"
api "KitexDemo/Kitex/kitex_gen/api"
)
// EchoImpl implements the last service interface defined in the IDL.
type EchoImpl struct{}
// Echo implements the EchoImpl interface.
func (s *EchoImpl) Echo(ctx context.Context, req *api.Request) (resp *api.Response, err error) {
// TODO: Your code here...
return
}
- 在Echo中构造对应的请求
2.启动服务端
启动服务器有两种方式:
- 使用go ide 启动服务器,或者手动输入命令启动
- 使用kitex工具生成的build.sh
- 执行build.sh
sh build.sh
,会生成一个outout目录 - output目录里面有bootstrap.sh文件和bin目录
- bin目录里是编译生成的二进制文件
- bootstrap.sh是启动服务器的脚本
- 执行
sh bootstrap.sh
就可以运行服务器
- 执行build.sh
3.创建Client
func main() {
c, err := echo.NewClient("example", client.WithHostPorts("0.0.0.0:8888")) //指定对端服务的IP
if err != nil {
log.Fatalln(err)
}
// 发起请求
req := &api.Request{Message: "my request"}
resp, err := c.Echo(context.Background(), req, callopt.WithRPCTimeout(2*time.Second))
if err != nil {
log.Fatalln(err)
}
log.Println(resp)
}
- NewClient 为 IDL 中定义的服务创建一个客户端,其第一个参数为调用的服务名,第二个参数
opts
是可变长的,用于传入设置参数,此处的client.WithHostPorts
用于指定对端服务的IP. - Background 返回一个非零的空上下文。它永远不会被取消,没有价值,也没有截止日期。它通常由 main 函数、初始化和测试使用,并作为传入请求的顶级上下文。
- WithRPCTimeout 指定 RPC 调用的 RPC 超时。 FIXME: callopt.WithRPCTimeout 仅在指定了 client.WithRPCTimeout 或 client.WithTimeoutProvider 时才起作用。
- client将接收到上文Echo()设置的返回值.
4.kitex服务注册与发现
- 目前kitex的服务器注册与发现已经对接了主流的服务注册与发现中心.
- Kitex 已经通过社区开发者的支持,完成了 ETCD、ZooKeeper、Eureka、Consul、Nacos、Polaris 多种服务发现模式,当然也支持 DNS 解析以及 Static IP 直连访问模式,建立起了强大且完备的社区生态,供用户按需灵活选用。
- 通过把server注册到注册中心里面,kitex去注册中心获取数据,内部实现负载均衡算法,速度会比走多层代理快一些,因为ip直连.
以 DNS Resolver 为例
import (
...
dns "github.com/kitex-contrib/resolver-dns"
"github.com/cloudwego/kitex/client"
...
)
func main() {
//第一个参数为服务名,使用服务名去做服务过滤,因为可能注册多个服务
client, err := echo.NewClient("echo", client.WithResolver(dns.NewDNSResolver()))
if err != nil {
log.Fatal(err)
}
// 将发现的对象传递进来
for {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
resp, err := client.Echo(ctx, &api.Request{Message: "Echo"})
cancel()
if err != nil {
log.Fatalln(err)
}
log.Println(resp)
time.Sleep(time.Second)
}
}
etcd为例子
基本同理,详情可以查看registry-etcd
安装
go get github.com/kitex-contrib/registry-etcd
如何与 Kitex 服务器一起使用?
import (
"github.com/cloudwego/kitex/pkg/rpcinfo"
"github.com/cloudwego/kitex/server"
etcd "github.com/kitex-contrib/registry-etcd"
)
func main() {
r, err := etcd.NewEtcdRegistry([]string{"127.0.0.1:2379"}) // r不应重复使用。
if err != nil {
log.Fatal(err)
}
// https://www.cloudwego.io/docs/tutorials/framework-exten/registry/#integrate-into-kitex
server, err := echo.NewServer(new(EchoImpl), server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: "echo"}), server.WithRegistry(r))
if err != nil {
log.Fatal(err)
}
err = server.Run()
if err != nil {
log.Fatal(err)
}
}
Kitex客户端如何使用?
import (
"github.com/cloudwego/kitex/client"
etcd "github.com/kitex-contrib/registry-etcd"
)
func main() {
r, err := etcd.NewEtcdResolver([]string{"127.0.0.1:2379"})
if err != nil {
log.Fatal(err)
}
client, err := echo.NewClient("echo", client.WithResolver(r))
if err != nil {
log.Fatal(err)
}
}
- 与 etcd 服务器 v3 兼容。