day14 入门微服务RPC框架—KiteX | 青训营笔记

297 阅读3分钟

题记

这是我参与「第五届青训营 」伴学笔记创作活动的第 14天,本文用于记录在青训营的学习笔记和一些心得。

day14 1月28日

KiteX

KiteX目前对windows的支持不完善,如果本地开发环境是windows的同学建议使用虚拟机或WSL2。

(Kitex的代码可以在windows上跑,但是代码生成工具对windows支持存在缺陷。)

安装代码生成工具:

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

image-20230127144646369

如果出现错误可以查看一下GOPATH/pkg/mod/github.com/cloudwego里面有没有代码

image-20230127145110218

定义IDL

使用IDL定义服务与接口:如果我们要进行RPC,就需要知道对方的接口是什么,需要传什么参数,同时也需要知道返回值是什么样的。这时候,就需要通过IDL来约定双方的协议,就像在写代码的时候需要调用某个函数,我们需要知道函数签名一样。

image-20230128143600193

  • namespace go api这里指我们定义了一个命名空间:api,api代表生成的代码中有一个目录:api。
  • struct Request{},表示我们编写一个请求消息体。struct中变量的格式为:不重复的编号:类型:命名
  • struct Response{},表示我们编写了一个返回消息体。
  • service Echo{}表示定义了一个Echo服务
  • Response echo(1:Request req)表示服务Echo中有一个叫做echo的方法,方法的返回消息为Response,请求消息为Request,请求消息的格式为:编号: 请求消息:命名
生成代码

使用以下命令生成代码: kitex -module "module_name" -service "service_name" xxx.thrift

-module module_name

  • 指定生成的代码所属的go模块,会影响生成代码里的import path
  • GOPATH/src 下的一个目录,那么可以不指定该参数;kitex 会使用GOPATH/src 开始的相对路径作为 import path 前缀。
  • 如果当前目录不在 $GOPATH/src 下,那么必须指定该参数。
  • 如果指定了 -module 参数,那么 kitex 会从当前目录开始往上层搜索 go.mod 文件

-service service_name

  • kitex 会生成构建一个服务的脚手架代码,参数 service_name 给出启动时服务自身的名字,通常其值取决于使用 Kitex 框架时搭配的服务注册和服务发现功能。

生成的基本框架:

image-20230128150551712

build.sh:构建脚本

kitex gen:lDL内容相关的生成代码,主要是基础的Server/Client代码。 main.go:程序入口

handler.go:用户在该文件里实现IDL service定义的方法

基本使用

服务默认监听8888端口

handler.go文件实现IDL里面的service方法,先定义一个空结构体,实现它的接口方法。

image-20230128151117498.

当代码逻辑比较复杂可以MVC分层。

Client发起请求

image-20230128152131692

NewClient 为 IDL 中定义的服务创建一个客户端。

echo.NewClient(“example”, client.WithHostPorts(“0.0.0.0:8888”))是创建一个客户端连接,第一个参数是服务名,要与生成代码中的service_name保持一致,第二个参数是指定server的地址和端口号(server默认占用8888端口)。

api.Request{Message: "my request"}:请求携带的数据

c.Echo(标准上下文(context.Backgroud()), 请求携带的数据, 指定 RPC 调用的 RPC 超时)

WithRPCTimeout 指定 RPC 调用的 RPC 超时。 FIXME: callopt.WithRPCTimeout 仅在指定了 client.WithRPCTimeout 或 client.WithTimeoutProvider 时才起作用。

服务注册与发现

建议先了解一下:服务注册与发现

server

image-20230128153851578

etcd.NewEtcdRegistry([]string{"127.0.0.1:2379"}) :创建一个etcd的注册,ectd占127.0.0.1的2379端口

server := hello.NewServer(new(HelloImpl),
      server.WithRegistry(r), //将server注册到etcd中
      
      //WithServerBasicInfo 为 RPCIInfo 中的客户端端点提供初始信息。
      //EndpointBasicInfo在创建后应该是不可变的。所以server名字是不可改变。
      server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{
         ServiceName: "example", 
      }),
   )
​
server.Run() //服务器运行

client

image-20230128154336921 etcd.NewEtcdResolver([]string{"127.0.0.1:2379"}):根据127.0.0.1:2379地址创建一个etcd组件实例

echo.MustNewClient(服务名,client.WithResolver(r))

  • 服务名要用于服务过滤
  • client.WithResolver,我们能看到最后把一个服务发现实例放到了 client 的 options 结构体中

WithTimeout: 取消此上下文会释放与其关联的资源,因此在该上下文中运行的操作完成后,代码应立即调用cancel。

生态

image-20230128153214676