Skip to content
鼓励作者:欢迎打赏犒劳

kitex初体验

官方教程地址:https://www.cloudwego.io/zh/docs/kitex/getting-started/quick_start/

我给大家演示下最最最简单的rpc服务。

前置工具

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

thrift文件

先定义一个idl/echo.thrift文件

text
namespace go api

struct Request {
    1: string message
}

struct Response {
    1: string message
}

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

生成代码

shell
kitex -module kitex-echo-demo -service echo_service idl/echo.thrift

启动

shell
go run .

可能你会遇到这个报错。这是因为window下环境和sonic依赖的版本问题导致的,需要更新下依赖版本即可

text
# github.com/bytedance/sonic/internal/rt
..\pkg\mod\github.com\bytedance\sonic@v1.13.3\internal\rt\stubs.go:33:22: undefined: GoMapIterator
..\pkg\mod\github.com\bytedance\sonic@v1.13.3\internal\rt\stubs.go:36:54: undefined: GoMapIterator

解决,更新到最新版

shell
go get -u github.com/bytedance/sonic@latest

实现服务逻辑

上面正常启动的话,就可以自定义逻辑了。

生成的代码中,你可以在 handler.go 文件中找到需要实现的服务接口。修改 Echo 函数的具体实现

go
package main

import (
    "context"
    "kitex-echo-demo/kitex_gen/api" // 请根据你的模块名调整导入路径
)

// EchoImpl 结构体实现了由 IDL 定义的接口
type EchoImpl struct{}

// Echo 方法是服务的核心逻辑
func (s *EchoImpl) Echo(ctx context.Context, req *api.Request) (resp *api.Response, err error) {
    // 简单地将请求消息返回
    return &api.Response{Message: req.Message}, nil
}

自定义启动端口

go
package main

import (
	api "kitex-echo-demo/kitex_gen/api/echo"
	"log"
	"net"

	"github.com/cloudwego/kitex/server"
)

func main() {
	// 指定服务监听地址
	addr, _ := net.ResolveTCPAddr("tcp", ":8888")
	svr := api.NewServer(new(EchoImpl), server.WithServiceAddr(addr))

	err := svr.Run()

	if err != nil {
		log.Println(err.Error())
	}
}

编写客户端代码

创建一个 client/main.go 文件

go
package main

import (
	"context"
	"kitex-echo-demo/kitex_gen/api"      // 根据你的模块名调整
	"kitex-echo-demo/kitex_gen/api/echo" // 根据你的模块名调整
	"log"
	"time"

	"github.com/cloudwego/kitex/client"
	"github.com/cloudwego/kitex/client/callopt"
)

func main() {
	// 创建客户端实例,指定服务端地址
	cli, err := echo.NewClient("echo_service", client.WithHostPorts("0.0.0.0:8888"))
	if err != nil {
		log.Fatal(err)
	}

	// 准备请求参数
	req := &api.Request{Message: "Hello, Kitex!"}

	// 发起 RPC 调用,并设置超时时间
	ctx := context.Background()
	resp, err := cli.Echo(ctx, req, callopt.WithRPCTimeout(3*time.Second))
	if err != nil {
		log.Fatal(err)
	}

	// 打印响应结果
	log.Printf("Response: %s", resp.Message)
}

结果:2025/09/20 19:06:01 Response: Hello, Kitex!

微服务注册与发现(基于 ETCD)

在微服务架构中,服务实例的动态注册和发现至关重要。KiteX 可以集成多种注册中心,如 ETCD、Nacos 等

前置条件

安装ETCD :官网:https://etcd.io/

在你的 Go 项目中引入相关库:

shell
go get github.com/kitex-contrib/registry-etcd

服务端(注册服务)

修改服务端的 main.go,将服务注册到 ETCD

go
package main

import (
	"kitex-echo-demo/kitex_gen/api/echo"
	"log"
	"net"

	"github.com/cloudwego/kitex/pkg/rpcinfo"
	"github.com/cloudwego/kitex/server"
	"github.com/kitex-contrib/registry-etcd"
)

func main() {
	// 初始化 ETCD 注册中心,传入 ETCD 的地址
	r, err := etcd.NewEtcdRegistry([]string{"127.0.0.1:2379"}) // 根据你的 ETCD 地址修改
	if err != nil {
		log.Fatal(err)
	}
	//特别注意,按理说不需要写死ip的,一般是自动获取,但是我在开发的时候发现注册到ETCD上的ip却不对,是一个随机的地址,
	//所以,这里我写死了我的本地IP地址
	addr, _ := net.ResolveTCPAddr("tcp", "192.168.0.101:8888")

	// 创建服务实例,并配置注册中心
	svr := echo.NewServer(new(EchoImpl),
		server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: "echo_service"}), // 服务名称
		server.WithRegistry(r), // 启用注册中心
		server.WithServiceAddr(addr),
	)

	err = svr.Run()
	if err != nil {
		log.Println(err.Error())
	}
}

客户端(发现服务)

修改客户端的 main.go,使其通过 ETCD 发现服务:

go
package main

import (
    "context"
    "log"
    "time"
    "kitex-echo-demo/kitex_gen/api"
    "kitex-echo-demo/kitex_gen/api/echo"
    "github.com/cloudwego/kitex/client"
    "github.com/kitex-contrib/registry-etcd"
    "github.com/cloudwego/kitex/client/callopt"
)

func main() {
    // 初始化 ETCD 解析器(用于服务发现)
    r, err := etcd.NewEtcdResolver([]string{"127.0.0.1:2379"}) // 根据你的 ETCD 地址修改
    if err != nil {
        log.Fatal(err)
    }

    // 创建客户端实例,配置使用 ETCD 进行服务发现
    cli, err := echo.NewClient("echo_service",
        client.WithResolver(r), // 配置服务发现
    )
    if err != nil {
        log.Fatal(err)
    }

    req := &api.Request{Message: "Hello, Service Discovery!"}
    ctx := context.Background()
    resp, err := cli.Echo(ctx, req, callopt.WithRPCTimeout(3*time.Second))
    if err != nil {
        log.Fatal(err)
    }

    log.Printf("Response: %s", resp.Message)
}

如有转载或 CV 的请标注本站原文地址