Go学习笔记(day12) | 青训营笔记

108 阅读2分钟

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

笨人纯小白,笔记包括一些上课学到的知识和课外总结的内容,如有错误请指正!

十五、Golang之kitex

15.1 Kitex的准备工作

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

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

安装成功后,使用以下命令验证是否安装成功:

kitex --version

thriftgo --version

15.2 创建IDL文件

Kitex最典型的情况是使用thrift定义的IDL来编写服务接口,实现客户端和服务端的通信

hello.thrift文件内容如下:

    namespace go api

    struct Request {
            1: string message
    }

    struct Response {
            1: string message
    }

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

15.3 生成代码

使用以下命令生成代码: kitex -module "mod_name" -service a.b.c hello.thrift

-module mod_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.png

然后执行命令go mod tidy下载依赖

15.4 一个问题及其解决

代码生成后的hello/hello.go报错,这是因为 github.com/apache/thrift 这个包使用的是v0.17.0版本的,但v0.14.0之后的包中很多函数增加了context上下文参数,所以很多函数由于缺少参数报错。

只需要修改go.mod中的require中github.com/apache/thrift v0.17.0github.com/apache/thrift v0.13.0然后再执行go mod tidy问题就能解决

15.5 客户端的调用

    import "example/kitex_gen/api/echo"
    import "github.com/cloudwego/kitex/client"
    import "example/kitex_gen/api"

    ...
    c, err := echo.NewClient("example", client.WithHostPorts("0.0.0.0:8888"))
    if err != nil {
      log.Fatal(err)
    }
    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)

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