go-zero
go-zero 是一套把工程脚手架、RPC/HTTP 运行时和服务治理组件放在同一条生产链路上的 Go 微服务工具箱。本册沿着“请求进入系统后如何被保护、合并、缓存、传输和生成”的顺序读源码。
本册问题地图
Section titled “本册问题地图”go-zero 的主线是“请求在高并发和下游不稳定时如何保持可控”:
- 自适应熔断依据什么变化? 它观察近期请求成功率、延迟或错误,把保护阈值随流量变化调整,而不是永远使用一个固定比例。
- 限流与熔断有什么区别? 限流限制进入速度,熔断限制对已不健康下游的继续调用;前者保护自身容量,后者隔离故障传播。
- SingleFlight/SharedCalls 合并了什么? 它们合并同一 key 的并发计算,减少缓存击穿时的重复查询,但不能替代缓存过期和失败回退策略。
- 缓存一致性为什么要单独设计? 删除、更新、空值和重建的时间顺序可能让旧值重新出现,延迟双删只是缓解窗口,不是强一致保证。
- zrpc 和 goctl 如何衔接? goctl 生成约定结构,zrpc 在运行时提供连接、拦截器和治理;生成代码减少样板,但不能替代运行时排障。
| 项 | 值 |
|---|---|
| 仓库 | zeromicro/go-zero |
| 本地路径 | E:\source\go\go-zero |
| 分支 | master |
| Commit | ebe46e1c(2026-08-13) |
| 最近 tag | v1.10.3 |
本册坐标均基于该 commit;上游演进后行号可能漂移。
它解决什么问题
Section titled “它解决什么问题”- 用客户端熔断、服务端自适应负载保护和超时拦截器,把局部故障限制在调用边界内。
- 用进程内窗口与 Redis Lua,把单机和分布式限流统一成可观测的决策点。
- 用
syncx.SingleFlight合并同 key 并发请求,避免缓存击穿时请求同时打到数据库。 - 用
zrpc把 gRPC、服务发现、健康检查、拦截器和优雅停机组合成默认运行时。 - 用
goctl把 API/Proto 解析成可运行工程,降低重复样板代码的维护成本。
| 模块 | 职责 | 关键入口 |
|---|---|---|
core/breaker |
Google SRE 风格客户端熔断 | NewBreaker |
core/load |
CPU、并发数、RT 联合判断的自适应 shedder | NewAdaptiveShedder |
core/limit |
Redis Lua 周期限流与令牌桶限流 | NewPeriodLimit、NewTokenLimiter |
core/syncx |
SingleFlight、原子值、锁与资源管理 |
NewSingleFlight |
core/collection、core/stores/cache |
本地缓存、Redis 缓存、击穿与空值保护 | Cache.Take、cacheNode.Take |
zrpc |
RPC server/client、拦截器、健康与发现 | zrpc.NewServer |
tools/goctl |
API/Proto 解析和工程生成 | generator.Generator.Generate |
读码入口顺序
Section titled “读码入口顺序”- 从
core/breaker.NewBreaker进入,理解“允许一次请求”与“请求结束上报结果”的 Promise 协议。 - 阅读
core/load.NewAdaptiveShedder,看滑动窗口如何推导最大并发和 CPU 降级因子。 - 对照
core/limit的 Lua 脚本调用,区分周期配额、令牌桶和本地 rescue limiter。 - 阅读
core/collection.Cache.Take与core/stores/cache.cacheNode.doTake,理解双检、空值占位和灾难快速失败。 - 最后进入
zrpc.NewServer与generator.Generate,看治理能力如何装配到运行时和生成产物。
- 整体架构:核心包、请求保护链和代码生成链
- 自适应熔断:滚动窗口、概率丢弃与 Promise
- 自适应限流与负载保护:周期限额、令牌桶和 shedder
- syncx 并发原语:SingleFlight、资源管理与锁边界
- 缓存一致性与击穿保护:本地缓存、Redis 缓存、空值和延迟清理
- zrpc 服务治理:拦截器、健康检查、发现和优雅停机
- goctl 代码生成:Proto 解析、工程上下文和分阶段生成
- 面试专题:源码级高频题与排障场景
| 对象 | 对照点 |
|---|---|
| Gin | Gin 解决 HTTP 路由链;go-zero 更强调服务治理和工程生成 |
| Sentinel | 都把统计窗口用于流控/熔断;go-zero 的 breaker 更偏客户端自适应丢弃 |
| Caffeine | 都有过期、LRU 和并发合并;go-zero 额外覆盖 Redis 和数据库灾难保护 |
| grpc-go | go-zero 在 gRPC 之上增加发现、拦截器默认组合和健康生命周期 |