Skip to content

快速开始

概述

本章将通过一个完整的示例,带你快速体验 CloudWeGo 的开发流程。我们将创建一个简单的 Hello World 服务,包含 Kitex RPC 服务和 Hertz HTTP 网关。

核心内容

环境准备

1. 安装 Go

确保已安装 Go 1.18 或更高版本:

bash
go version
# go version go1.21.0 linux/amd64

安装 Go 的详细步骤:

  • Windows

    1. 访问 Go 官方下载页面
    2. 下载对应版本的安装包
    3. 运行安装程序,按照向导完成安装
    4. 配置环境变量 GOROOTGOPATH
    5. %GOROOT%\bin 添加到 PATH
  • macOS

    bash
    # 使用 Homebrew
    brew install go
    
    # 或手动安装
    # 下载并运行安装包
  • Linux

    bash
    # Ubuntu/Debian
    sudo apt update
    sudo apt install golang
    
    # CentOS/RHEL
    sudo yum install golang
    
    # 或从源码安装

2. 安装代码生成工具

bash
# 安装 Kitex 代码生成工具
go install github.com/cloudwego/kitex/tool/cmd/kitex@latest

# 安装 Hertz 代码生成工具
go install github.com/cloudwego/hertz/cmd/hz@latest

# 验证安装
kitex --version
hz --version

安装注意事项:

  • 确保 GOPATH/bin 在系统 PATH
  • 如果遇到网络问题,可配置 Go 代理:
    bash
    go env -w GOPROXY=https://goproxy.cn,direct

3. 安装 Thrift IDL 编译器

bash
# macOS
brew install thrift

# Ubuntu/Debian
sudo apt-get install thrift-compiler

# CentOS/RHEL
sudo yum install thrift-devel

# 或使用 go 版本
go install github.com/cloudwego/thriftgo@latest

4. 安装 Protobuf 编译器(可选)

如果使用 Protobuf 协议,还需要安装:

bash
# macOS
brew install protobuf

# Ubuntu/Debian
sudo apt-get install protobuf-compiler

# 安装 Go Protobuf 插件
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install github.com/cloudwego/kitex/tools/protoc-gen-kitex@latest

创建项目结构

bash
mkdir hello-cloudwego
cd hello-cloudwego
go mod init example

# 创建目录结构
mkdir -p idl kitex-server hertz-gateway

项目结构:

hello-cloudwego/
├── idl/
│   └── hello.thrift          # IDL 定义
├── kitex-server/             # Kitex RPC 服务
│   ├── handler.go
│   └── main.go
├── hertz-gateway/            # Hertz HTTP 网关
│   └── main.go
└── go.mod

定义 IDL

创建 idl/hello.thrift

thrift
namespace go hello

struct Request {
    1: string name
}

struct Response {
    1: string message
    2: i64 timestamp
}

service HelloService {
    Response SayHello(1: Request req)
    Response StreamHello(1: Request req) (streaming)
}

Kitex 服务端

1. 生成代码

bash
cd kitex-server
kitex -module example -service hello ../idl/hello.thrift

2. 实现服务处理器

创建 kitex-server/handler.go

go
package main

import (
    "context"
    "time"
    
    "example/kitex_gen/hello"
)

type HelloHandler struct{}

func (h *HelloHandler) SayHello(ctx context.Context, req *hello.Request) (*hello.Response, error) {
    return &hello.Response{
        Message:   "Hello, " + req.Name + "!",
        Timestamp: time.Now().Unix(),
    }, nil
}

func (h *HelloHandler) StreamHello(req *hello.Request, stream hello.HelloService_StreamHelloServer) error {
    for i := 0; i < 5; i++ {
        err := stream.Send(&hello.Response{
            Message:   "Hello stream message " + string(rune(i+1)),
            Timestamp: time.Now().Unix(),
        })
        if err != nil {
            return err
        }
        time.Sleep(time.Second)
    }
    return nil
}

3. 启动服务

创建 kitex-server/main.go

go
package main

import (
    "log"
    
    "github.com/cloudwego/kitex/server"
    "example/kitex_gen/hello/helloservice"
)

func main() {
    svr := helloservice.NewServer(&HelloHandler{},
        server.WithServiceAddr(&net.TCPAddr{
            Port: 8888,
        }),
    )
    
    log.Println("Kitex server starting on :8888")
    if err := svr.Run(); err != nil {
        log.Fatalf("server stopped: %v", err)
    }
}

Hertz HTTP 网关

1. 创建网关服务

创建 hertz-gateway/main.go

go
package main

import (
    "context"
    "log"
    "time"
    
    "github.com/cloudwego/hertz/pkg/app"
    "github.com/cloudwego/hertz/pkg/app/server"
    "github.com/cloudwego/hertz/pkg/common/utils"
    "github.com/cloudwego/hertz/pkg/protocol/consts"
    
    "example/kitex_gen/hello"
    "example/kitex_gen/hello/helloservice"
)

var client helloservice.Client

func main() {
    // 创建 Kitex 客户端
    client = helposeservice.MustNewClient("hello",
        client.WithHostPorts("127.0.0.1:8888"),
    )
    
    // 创建 Hertz 服务
    h := server.Default()
    
    // 注册路由
    h.GET("/hello/:name", func(ctx context.Context, c *app.RequestContext) {
        name := c.Param("name")
        
        // 调用 Kitex 服务
        resp, err := client.SayHello(ctx, &hello.Request{
            Name: name,
        })
        if err != nil {
            c.String(consts.StatusInternalServerError, err.Error())
            return
        }
        
        c.JSON(consts.StatusOK, utils.H{
            "message":   resp.Message,
            "timestamp": resp.Timestamp,
        })
    })
    
    // SSE 流式接口
    h.GET("/stream/:name", func(ctx context.Context, c *app.RequestContext) {
        name := c.Param("name")
        
        // 设置 SSE 响应头
        c.Response.Header.Set("Content-Type", "text/event-stream")
        c.Response.Header.Set("Cache-Control", "no-cache")
        c.Response.Header.Set("Connection", "keep-alive")
        
        // 创建流式请求
        stream, err := client.StreamHello(ctx, &hello.Request{
            Name: name,
        })
        if err != nil {
            c.String(consts.StatusInternalServerError, err.Error())
            return
        }
        
        // 接收流式响应并转发
        for {
            resp, err := stream.Recv()
            if err != nil {
                break
            }
            
            // 发送 SSE 事件
            c.Response.BodyWriter().Write([]byte(
                "data: " + resp.Message + "\n\n",
            ))
            c.Response.BodyWriter().Flush()
        }
    })
    
    log.Println("Hertz gateway starting on :8080")
    h.Spin()
}

运行服务

1. 启动 Kitex 服务

bash
cd kitex-server
go mod tidy
go run .

2. 启动 Hertz 网关

bash
cd hertz-gateway
go mod tidy
go run .

3. 测试服务

bash
# 测试普通请求
curl http://localhost:8080/hello/World

# 测试流式请求
curl http://localhost:8080/stream/World

使用 hz 工具创建项目

Hertz 提供了 hz 工具快速创建项目:

bash
# 创建新项目
hz new -mod example -idl idl/hello.thrift

# 更新现有项目
hz update -idl idl/hello.thrift

项目依赖

go.mod 文件:

go
module example

go 1.21

require (
    github.com/cloudwego/hertz v0.7.0
    github.com/cloudwego/kitex v0.5.0
    github.com/cloudwego/netpoll v0.4.0
)

常见问题解决

1. 环境配置问题

问题:找不到 kitex 或 hz 命令

解决方法

  • 确保 GOPATH/bin 在系统 PATH
  • 检查 Go 代理配置:go env GOPROXY
  • 重新安装:go install github.com/cloudwego/kitex/tool/cmd/kitex@latest

问题:Thrift 编译器安装失败

解决方法

  • 使用 go 版本的 thriftgo:go install github.com/cloudwego/thriftgo@latest
  • 检查网络连接,使用国内镜像

2. 代码生成问题

问题:生成的代码有编译错误

解决方法

  • 检查 Go 版本是否符合要求(1.18+)
  • 检查 IDL 文件语法是否正确
  • 清理生成的代码并重新生成

问题:找不到依赖包

解决方法

  • 运行 go mod tidy 下载依赖
  • 检查 go.mod 文件配置
  • 配置 Go 代理:go env -w GOPROXY=https://goproxy.cn,direct

3. 运行时问题

问题:服务启动失败

解决方法

  • 检查端口是否被占用
  • 检查依赖是否正确安装
  • 查看错误日志,定位具体问题

问题:客户端调用失败

解决方法

  • 检查服务端是否正常运行
  • 检查网络连接是否正常
  • 检查服务地址和端口配置

4. 性能问题

问题:服务响应慢

解决方法

  • 检查网络连接
  • 优化代码逻辑
  • 配置适当的连接池大小

问题:内存占用高

解决方法

  • 检查是否有内存泄漏
  • 优化数据结构
  • 配置适当的 GC 参数

5. 调试技巧

启用详细日志

bash
# 设置日志级别
export KITEX_LOG_LEVEL=debug
export HERTZ_LOG_LEVEL=debug

使用 pprof 进行性能分析

bash
# 启用 pprof
import _ "net/http/pprof"

# 在 main 函数中添加
go func() {
    http.ListenAndServe(":6060", nil)
}()

小结

本章通过一个完整的示例,带你体验了 CloudWeGo 的开发流程:

  1. 环境准备:安装 Go、代码生成工具、Thrift 编译器
  2. IDL 定义:使用 Thrift 定义服务接口
  3. Kitex 服务端:生成代码、实现处理器、启动服务
  4. Hertz 网关:创建 HTTP 网关,调用 Kitex 服务
  5. 流式处理:实现 SSE 流式响应
  6. 问题解决:常见问题的排查和解决方法

在下一章中,我们将深入学习 IDL 的语法和使用技巧。