go-zero 微服务实战

从单体到微服务:怎么拆、怎么生成、服务之间怎么发现与调用、网关怎么收口。一张架构图先建立全局观。

微服务架构 服务拆分 goctl 生成 服务发现 API 网关 部署编排

go-zero 微服务长什么样

典型形态:一个对外 API 网关 + 多个对内 RPC 服务,全部通过 etcd 自动注册发现。客户端只认网关,网关再调度内部 RPC。

客户端 Web/App user-api 网关(rest) JWT/鉴权 user-rpc zrpc order-rpc zrpc pay-rpc zrpc etcd 注册中心 服务发现 MySQL/Redis 数据层

实线 = 调用链路;绿色虚线 = 服务启动时向 etcd 注册、调用方从 etcd 拉取节点。

怎么拆服务

拆分的依据不是「技术层」,而是「业务域」。一个域一个 RPC 服务,对外再包一层 API 网关。

✅ 按业务域拆
用户、订单、支付各自独立 RPC 服务,边界清晰、可独立扩容与发布。
❌ 按技术层拆
不要搞「common-rpc」「util-rpc」,会变成分布式大泥球,跨服务调用爆炸。
网关做收口
所有外部流量先进 user-api 这类 rest 网关,统一鉴权、限流、参数校验。
内部只用 RPC
服务之间永远走 zrpc,不互相直连数据库,避免数据耦合。

用 goctl 一键生成微服务

go-zero 的精髓:先写契约(.api / .proto / SQL),再让工具产出全部样板。

1

生成 API 网关

写好 user.api 后:goctl api go -api user.api -dir user-api

2

生成 RPC 服务

写好 user.proto 后:goctl rpc protoc user.proto --go_out=. --go-grpc_out=. --zrpc_out=. -m

3

生成数据模型

goctl model mysql ddl -src user.sql -dir ./internal/model -c 产出带缓存的 CRUD。

4

把 RPC 配进网关

网关的 config 里加 UserRpc zrpc.RpcClientConf,svc 里建 client,logic 里直接调用。

网关 logic 调用下游 RPC

func (l *LoginLogic) Login(req *types.LoginReq) (*types.LoginResp, error) {
    // 通过注入的 svcCtx 拿到 RPC 客户端
    resp, err := l.svcCtx.UserRpc.Login(l.ctx, &user.LoginRequest{
        Username: req.Username,
        Password: req.Password,
    })
    if err != nil {
        return nil, err
    }
    return &types.LoginResp{Token: resp.Token}, nil
}

服务注册与发现(etcd)

RPC 服务启动时自动注册到 etcd,调用方自动发现并负载均衡。你只需要在 yaml 里写 etcd 地址。

RPC 服务端配置(注册)

Name: user.rpc            # 服务名,调用方靠它找你
ListenOn: 0.0.0.0:8080
Etcd:
  Hosts:
    - 127.0.0.1:2379
  Key: user.rpc           # 注册到 etcd 的 key

调用方配置(发现)

UserRpc:
  Etcd:
    Hosts:
      - 127.0.0.1:2379
    Key: user.rpc         # 按 key 找到 user-rpc 的所有节点
调用方无需写死 IP:Port,节点扩缩容、故障切换对代码透明,框架自动从 etcd 拉列表并做负载均衡。

API 网关要做的事

网关是内外边界,把横切关注点集中处理,下游 RPC 保持纯粹。

统一鉴权
在中间件里校验 JWT,合法才放行到下游。
参数校验
.api 定义的类型自动做 json 绑定基础校验。
限流防刷
网关层 periodlimit,拦掉恶意流量。
聚合编排
一个接口需要多个 RPC 时,在 logic 里编排聚合。

容器化与编排

每个服务独立打镜像、独立部署,互不影响发布节奏。

生成 Dockerfile

goctl docker -go user-api.go

产出多阶段构建的 Dockerfile,体积小、启动快。

生成 K8s 部署

goctl kube deploy \
  -name user-api \
  -namespace default \
  -image user-api:v1 \
  -port 8888 \
  -o user-api.yaml

直接产出 Deployment + Service,改改镜像就能上集群。

微服务不是免费的:服务越多,运维(链路追踪、统一日志、配置中心)成本越高。go-zero 已经内置了大部分能力,但 etcd、Prometheus 这些基础设施要提前规划好。
一句话回顾:业务域拆成多个 RPC 服务,对外用 rest 网关收口,etcd 自动注册发现,goctl 一条命令把样板全生成,最后 docker + kube 各自部署。你专注写 logic 就行。