Fiber 不提供 Memcached 集成,因其是极简框架,不内置缓存后端或抽象接口;必须手动使用 gomemcache 客户端,在 handler 中显式调用读写操作,且需全局复用 client、规范 key 命名、处理 ErrCacheMiss 等错误。

为什么 Fiber 本身不提供 Memcached 集成
Fiber 是一个极简 HTTP 框架,它不内置任何缓存后端(包括 Redis 或 Memcached),也不抽象 cache 接口。所谓“配置 Memcached 缓存”,实际是你在 handler 里手动调用 gomemcache 客户端读写,Fiber 不参与、不拦截、不封装——它只管路由和响应。别找 app.Use(cache.Middleware) 这类东西,不存在。
必须用 github.com/bradfitz/gomemcache/memcache
这是当前 Go 生态唯一在线上高并发场景验证过的 Memcached 客户端。其他库要么连接池泄漏,要么哈希漂移,要么 timeout 不生效。你用错客户端,缓存层会先于业务崩掉。
-
mc := memcache.New("10.0.1.10:11211", "10.0.1.11:11211")—— 支持多节点,但默认是取模哈希,扩容时缓存全失效;生产必须换memcache.NewSelector() -
mc.Timeout = 100 * time.Millisecond—— 默认是 0(无限等待),不设就卡死 goroutine -
mc.MaxIdleConns = 20—— 默认是 1,QPS 超过 50 就排队,别信“够用了” - 所有 value 必须是
[]byte,结构体要json.Marshal后再存,字段必须首字母大写 +json:tag
怎么在 Fiber handler 里安全使用 Memcached
不要每次请求都 new client,全局复用一个 *memcache.Client 实例。缓存逻辑要包裹错误处理,且明确区分 memcache.ErrCacheMiss 和其他 error。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 读缓存失败(
memcache.ErrCacheMiss)不是异常,应继续查 DB;其他 error(如超时、连接拒绝)才该记录日志或降级 - 写缓存时,
Expiration设为秒数,别传 0(永不过期)或负数(立即过期) - key 命名需带业务前缀和版本号,例如
"article:v2:123",避免不同服务或结构体变更导致冲突 - 如果用到 CAS(Check-And-Set),必须自己实现重试逻辑,
gomemcache的Get/CompareAndSwap是分离调用,不自动重试
func getArticle(c *fiber.Ctx) error {
id := c.Params("id")
key := "article:v2:" + id
<pre class="brush:php;toolbar:false;">item, err := mc.Get(key)
if err == nil {
var art Article
if json.Unmarshal(item.Value, &art) == nil {
return c.JSON(art)
}
} else if err != memcache.ErrCacheMiss {
log.Printf("memcache.Get %s failed: %v", key, err)
}
// fallback to DB
art, _ := db.FindArticle(id)
data, _ := json.Marshal(art)
_ = mc.Set(&memcache.Item{
Key: key,
Value: data,
Expiration: 3600,
})
return c.JSON(art)
}
跨服务共享 Memcached 时最易忽略的点
如果你的 Rails、Python 或 Node 服务也在写同一个 Memcached 实例,协议层面没问题,但数据契约极易断裂。
- 所有服务必须统一序列化格式(推荐 JSON,禁用 Ruby 的 Marshal 或 Python 的 pickle)
- key 命名规范必须书面约定,比如
"user:profile:{id}"中{id}是字符串还是整数,大小写是否敏感 - TTL 必须协同:Rails 写入设了 1 小时,Go 读取后又 Set 了永不过期,会导致陈旧数据滞留
- 没有分布式锁,多个服务同时更新同一 key 时,靠
CompareAndSwap或应用层版本号控制,别依赖“先读后写”的竞态逻辑
Memcached 是裸协议服务,它不校验你的 JSON 是否合法,也不提醒你字段缺失——出问题时,往往表现为“数据偶尔为空”或“解析 panic”,而不是明显报错。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










