用 Kitex 快速上手从“Hello”到自定义 `Add` 方法的完整实战

83 阅读5分钟

一、为什么选 Kitex?

  • 高性能 Go RPC 框架:字节跳动内部广泛使用,延迟与吞吐表现优秀。
  • 工业级 IDL 流程:基于 Thrift/Protobuf,代码生成器一键产出骨架代码。
  • 生态完善:配套中间件、治理能力(限流、熔断、重试、链路追踪等)齐全。

二、前置准备

  • 操作系统:Linux / macOS / Windows(均可)

  • Go:建议 ≥ 1.18(推荐 1.21+)

  • Git 与 Docker(可选,用于容器化运行)

  • 已安装 kitex 与 Thrift/Protobuf(示例基于 Thrift)

    # 安装 kitex 命令行(推荐使用 Go 1.20+)
    go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
    
    # 可选:安装 thrift(不同平台安装方式略有差异)
    # macOS (brew):brew install thrift
    # Ubuntu:sudo apt-get install thrift-compiler
    

三、获取并运行官方示例

3.1 克隆示例仓库

git clone https://github.com/cloudwego/kitex-examples.git
cd kitex-examples/hello

3.2 启动服务端

go run .

看到类似日志即表示成功:

2024/01/18 20:35:08.857352 server.go:83: [Info] KITEX: server listen at addr=[::]:8888

3.3 启动客户端(另开一个终端)

go run ./client

每隔一秒输出一行响应:

2024/01/18 20:39:59 Response({Message:my request})
2024/01/18 20:40:00 Response({Message:my request})
...

四、用 Docker 一键构建与运行(可选)

在仓库根目录:

cd kitex-examples
docker build -t kitex-examples .

分别启动:

# 服务端
docker run --network host kitex-examples ./hello-server
# 客户端
docker run --network host kitex-examples ./hello-client

看到服务端监听 :8888,客户端每秒打印一次响应,即容器化运行成功。

五、在示例上新增自定义 RPC 方法

本节目标:在 Hello 服务上新增一个求和方法 add(first, second) -> sum

5.1 修改 IDL(hello.thrift

原始内容大致如下:

namespace go api

struct Request {
  1: string message
}

struct Response {
  1: string message
}

service Hello {
  Response echo(1: Request req)
}

新增请求/响应结构与方法:

namespace go api

struct Request {
  1: string message
}

struct Response {
  1: string message
}

struct AddRequest {
  1: i64 first
  2: i64 second
}

struct AddResponse {
  1: i64 sum
}

service Hello {
  Response echo(1: Request req)
  AddResponse add(1: AddRequest req)
}

小贴士:IDL 是“契约”。服务端与客户端都以它为准,修改后需要重新生成代码。

5.2 生成(或更新)代码

hello/ 目录执行:

kitex -module "github.com/cloudwego/kitex-examples" -service a.b.c hello.thrift

执行后会:

  • 更新 ./handler.go,为新方法 Add 生成空实现;
  • 更新/生成 ./kitex_gen 下与 Thrift 绑定的代码。

如果你是第一次在自己项目里用:建议 go mod init your/module/path,并用 -module 指向该路径。

5.3 实现服务端逻辑(handler.go

生成器会给出一个空方法:

// Add implements the HelloImpl interface.
func (s *HelloImpl) Add(ctx context.Context, req *api.AddRequest) (resp *api.AddResponse, err error) {
    // TODO: Your code here...
    return
}

改为可用实现(中文注释):

// Add 实现:将两个参数相加后返回
func (s *HelloImpl) Add(ctx context.Context, req *api.AddRequest) (*api.AddResponse, error) {
    // 参数校验(这里简单演示,实际可加更多保护)
    // 例如:限制数值范围、处理溢出等
    sum := req.GetFirst() + req.GetSecond()
    return &api.AddResponse{Sum: sum}, nil
}

经验:尽量避免在实现里 panic;返回明确的错误(error),并在调用端做重试/兜底。

5.4 在客户端发起调用(client/main.go

示例客户端默认只调用 Echo,我们加上 Add 调用:

for {
    // 1) 继续调用 echo
    req := &api.Request{Message: "my request"}
    resp, err := client.Echo(context.Background(), req)
    if err != nil {
        log.Fatal(err) // 生产环境建议不要 fatal,可改为重试与降级
    }
    log.Println(resp)
    time.Sleep(time.Second)

    // 2) 新增调用 add
    addReq := &api.AddRequest{First: 512, Second: 512}
    addResp, err := client.Add(context.Background(), addReq)
    if err != nil {
        log.Fatal(err)
    }
    log.Println(addResp) // 期望 Sum=1024
    time.Sleep(time.Second)
}

六、重新运行并验证

6.1 启动服务端

go run .

6.2 启动客户端

go run ./client

6.3 期望输出

  • 服务端:
2024/01/18 21:07:43.638115 server.go:83: [Info] KITEX: server listen at addr=[::]:8888
  • 客户端:
2024/01/18 21:07:52 Response({Message:my request})
2024/01/18 21:07:53 AddResponse({Sum:1024})
2024/01/18 21:07:54 Response({Message:my request})
2024/01/18 21:07:55 AddResponse({Sum:1024})
...

恭喜!你已经完成了一个从 IDL 到服务实现从客户端调用到运行验证 的完整闭环。

七、项目结构速览(示例)

hello/
├─ handler.go            # 业务实现:Echo / Add
├─ kitex_gen/            # 由 kitex 生成的代码(不要手改)
│  └─ api/...
├─ main.go               # 服务端入口
├─ client/
│  └─ main.go            # 客户端入口
└─ hello.thrift          # IDL:新增 Add 方法后作为“契约”的源

八、常见问题(FAQ)与排错建议

  1. kitex: command not found
  • 确认已安装:go install github.com/cloudwego/kitex/tool/cmd/kitex@latest
  • $GOPATH/bin$HOME/go/bin 加入 PATH
  1. 生成代码后导入报错 / 找不到包
  • 确认 go.modmodule 路径与 -module 参数一致。
  • 运行 go mod tidy 修复依赖。
  1. 端口占用
  • 服务端默认监听 :8888;被占用可在 main.go 中改端口,或停掉占用者:

    lsof -i :8888
    kill -9 <PID>
    
  1. Windows 构建问题
  • 尽量使用 PowerShell 或 WSL;Thrift 组件请从官方或包管理器安装。
  • 编译失败时,先清理缓存:go clean -modcache,再 go mod tidy
  1. Docker 网络通信失败
  • 示例用 --network host 简化联通;在非 Linux 环境上(如 macOS)host 行为不同,可改为自定义网络并通过容器名互连。

九、进阶建议(可逐步加上)

  • 参数校验:为 AddRequest 增加范围、类型、空值检查;返回带错误码的业务错误。
  • 超时控制:在客户端调用处使用 context.WithTimeout,避免调用悬挂。
  • 重试与熔断:利用 Kitex 中间件配置重试策略、失败统计与熔断器。
  • 可观测性:接入日志打点、Prometheus 指标、OpenTelemetry 链路追踪。
  • 限流与鉴权:在服务端添加全局/接口级限流器与简单 Token 校验。

十、命令清单(速查)

# 1. 克隆示例
git clone https://github.com/cloudwego/kitex-examples.git
cd kitex-examples/hello

# 2. 本地运行
go run .                # 服务端
go run ./client         # 客户端

# 3. 修改 IDL 并生成代码
#   (在 hello/ 下执行;注意 -module 与你的 go.mod 对应)
kitex -module "github.com/cloudwego/kitex-examples" -service a.b.c hello.thrift

# 4. Docker(在仓库根目录)
cd ..
docker build -t kitex-examples .
docker run --network host kitex-examples ./hello-server
docker run --network host kitex-examples ./hello-client

从“跑通官方示例”到“新增一个可用方法”,你已经掌握了 Kitex 的核心开发路径:定义 → 生成 → 实现 → 调用。接下来不妨把 Add 扩展为一个计算服务(支持多操作、参数校验、错误码、监控埋点),再将其打包成 Docker 镜像部署到你的测试环境。一步步升级,你就走上了生产级 RPC 服务的正轨。祝你编码愉快!