你的判断完全正确:Gin 是轻量 Web/HTTP 框架,不含服务发现、熔断限流、链路追踪、配置中心、代码生成、gRPC 这套微服务治理生态;而 go-zero 是完整微服务框架,把这一整套都做进了框架。本文逐项讲清 go-zero 这六项能力是怎么实现的、怎么用。
基于标准库 net/http,提供路由、中间件、参数绑定、校验、JSON 渲染。它聚焦于「把 HTTP 接口写好」这一件事,不内置任何微服务治理:服务发现、熔断限流、链路追踪、配置中心、代码生成、gRPC 统统要你自己接第三方库或自己写。
go-zero 是「带电池」的微服务框架:服务发现、负载均衡、自适应熔断、限流、降载、链路追踪、配置热更新、代码生成、gRPC 全部内置。多数能力零配置或几行 yaml 即生效,不用自己拼装生态。
net/http 上面一层(Web 框架);go-zero 在 Web 框架之上再叠一层「服务治理」。go-zero 自己也有 HTTP 层(rest),但它额外的价值是让多个服务协同且稳定。所以两者不是"同层两个选手",而是"不同层的工具"。
| 能力 | Gin 自带? | 说明 |
|---|---|---|
| 路由 / 中间件 / 参数绑定 / 校验 | 自带 | Web 开发核心,Gin 的强项。 |
| JSON / HTML 渲染 | 自带 | 内置 c.JSON / c.HTML。 |
| Logger / Recovery | 自带 | gin.Logger()、gin.Recovery()。 |
| ORM / 数据库访问 | 不给 | 需外接 GORM / sqlx / ent。 |
| 依赖注入容器 | 不给 | 需 Wire / 手写 ServiceContext。 |
| 服务发现 / 注册中心 | 不给 | 需外接 etcd / consul / nacos 客户端自己实现。 |
| 熔断 / 限流 | 不给 | 需外接 sentinel-golang / 自写中间件。 |
| 链路追踪 | 不给 | 需外接 OpenTelemetry / jaeger SDK 自己埋点。 |
| 配置中心(Apollo/Nacos) | 不给 | 需自己拉取并热更新。 |
| 代码生成 | 不给 | 无脚手架生成能力。 |
| gRPC | 不给 | 需直接用 google.golang.org/grpc 自己搭。 |
| 治理能力 | Gin | go-zero | go-zero 怎么给 |
|---|---|---|---|
| 服务发现 | 无 | 有 | core/discov + zrpc,etcd/consul/nacos/k8s 自动注册发现 |
| 熔断限流 | 无 | 有 | core/breaker(自适应)、core/limit(令牌桶/窗口),拦截器自动注入 |
| 链路追踪 | 无 | 有 | Telemetry 配置块接 OpenTelemetry,handler/RPC 自动建 span |
| 配置中心 | 无 | 部分 | 内置 yaml/json/toml + 热更新 + 环境变量;Apollo/Nacos 需自行适配 |
| 代码生成 | 无 | 有 | goctl:从 .api / .proto / SQL 一键生成服务骨架 |
| gRPC | 无 | 有 | zrpc:封装 grpc,加健康检查 / 指标 / 追踪 / 发现 / 熔断 |
etcd,也支持 consul / nacos / kubernetes / dns / static。 ListenOn 地址写到 etcd 的 Key(如 user.rpc)下。Watch 该 Key,拿到实时实例列表;实例掉线自动摘除。# etc/user.yaml —— RPC 服务 Name: user.rpc ListenOn: 0.0.0.0:8080 Etcd: Hosts: - 127.0.0.1:2379 Key: user.rpc # 注册到这个 key
# etc/user-api.yaml —— 网关调用它 UserRpc: Etcd: Hosts: - 127.0.0.1:2379 Key: user.rpc # 按 key 发现
breaker.Do。// 手动使用 err := breaker.Do("user.rpc.Login", func() error { _, e := client.Login(ctx, req) return e }, nil)
// 网关加令牌桶限流中间件 import "github.com/zeromicro/go-zero/rest/httpx" server.Use(limit.NewTokenLimiter( rds, // redis 实例 "user-api:limit", // key 100, // rate/period limit.Options{}))
# 服务配置里加 Telemetry 块 Telemetry: Name: user-rpc # 服务名 Endpoint: 127.0.0.1:4317 # OTel collector Sampler: 1.0 # 采样率 Batcher: otlpgrpc # 上报协议
配好即可,span 自动生成、跨 RPC 自动串联。logx 还会把 traceId/spanId 注入结构化日志。
tracer.Start 建 span、并手动把 trace context 注入 gRPC/HTTP 出站元数据。go-zero 这套「自动建 span + 自动传播」正是治理内置的体现。
yaml / json / toml,结构体映射。conf.MustLoad + ServiceConf.SetUp() 初始化全部子系统。# 典型服务配置 Name: user-api Host: 0.0.0.0 Port: 8888 UserRpc: Etcd: { Hosts: [127.0.0.1:2379], Key: user.rpc }
configx 自定义 loader,把远端配置拉下来喂给 conf。.api → HTTP 服务骨架(handler/logic/svc/types/config)。.proto → gRPC(zrpc) 服务端与客户端桩。# 生成 HTTP 网关 goctl api go -api user.api -dir user-api # 生成 gRPC 服务(含 zrpc) goctl rpc protoc user.proto \ --go_out=. --go-grpc_out=. --zrpc_out=. -m # 从建表语句生成 Model goctl model mysql ddl -src user.sql -dir ./model -c # 生成 K8s 部署 goctl kube deploy -name user-api -image user-api:latest -port 8888 # 导出模板自定义风格 goctl template init
internal/logic/*.go,且这个文件永远不会被重新生成覆盖。开发者专注业务,样板全交给工具。Gin 没有任何脚手架生成,目录与样板都得手搭。
grpc.Server 上封装:加健康检查、Prometheus 指标、OpenTelemetry 追踪。zrpc.Client)自动加:服务发现、P2C 负载均衡、熔断。.proto 强类型契约,protobuf 二进制序列化,比 JSON 小快。syntax = "proto3"; package user; service User { rpc Login(LoginReq) returns (LoginResp); } message LoginReq { string username=1; string password=2; } message LoginResp { string token=1; }
写好 goctl rpc protoc 一键生成 server/client,调用方在 logic 里直接 svcCtx.UserRpc.Login(...)。
google.golang.org/grpc 手搭 server/client,并自行补上服务发现、负载均衡、熔断、追踪——而这些在 go-zero 的 zrpc 里是「生成即得」的默认行为。
user.api + user.proto + SQL,goctl 生成网关 / RPC / Model(代码生成 ✓)。Etcd 注册;网关 yaml 配 UserRpc.Etcd 发现(服务发现 ✓ + P2C)。Telemetry 块(链路追踪 ✓,自动 span)。server.Use(limit.NewTokenLimiter(...))(限流 ✓);zrpc 客户端默认带熔断(熔断 ✓)。internal/logic,通过注入的 svcCtx.UserRpc 调下游(gRPC/zrpc ✓)。