连接失败主因是memcached服务未运行、地址错误或网络不通:本地需启动服务并用telnet测试,docker中应改用host.docker.internal或宿主机ip而非127.0.0.1。

连接失败时别急着改代码,先确认 Memcached 实例是否真在跑
绝大多数 connection refused 或超时问题,根源不在 Go 代码里,而在服务端没起来、地址写错或网络不通。
本地开发:运行 memcached -p 11211 -m 64 启动;Mac 用户用 Homebrew 安装后需手动 brew services start memcached,它默认不自启。
Docker 场景下,Go 进程连 127.0.0.1:11211 是无效的——容器内 localhost ≠ 宿主机。应改用 host.docker.internal:11211(Mac/Win)或宿主机真实 IP(Linux)。
快速验证:终端执行 telnet 127.0.0.1 11211(或 nc -zv 127.0.0.1 11211),通了再查代码。
mc.Set() 成功但 mc.Get() 返回 nil?不是丢数据,是 key 或 value 不合规
gomemcache 对输入极其“诚实”:非法 key 或非 []byte value 会静默失败——Set() 返回 nil error,但实际没存进去。
key 必须是纯 ASCII 字符串:不能含空格、中文、\x00 等控制字符;推荐用正则 ^[a-zA-Z0-9_:.-]+$ 预检。
value 必须是 []byte:传 string 要转 []byte(s);传 struct 必须先 json.Marshal,取回再 json.Unmarshal。
过期时间单位是秒,不是毫秒:Expiration: 300 表示 5 分钟;设成 0 表示永不过期(慎用)。
并发读写时出现 server error 或 key 丢失?检查 Timeout 和 MaxIdleConns
gomemcache 默认 Timeout = 0(无限等待),一次卡住就拖垮整个 HTTP 请求;默认 MaxIdleConns = 1,高 QPS 下连接池迅速耗尽。
务必在初始化 client 后立即设置:mc.Timeout = 100 * time.Millisecond;mc.MaxIdleConns = 10(根据压测调,通常 10–30 足够)。
不要在每次请求都新建 *memcache.Client,全局复用一个实例——它本身线程安全,内部已管理连接池。
批量读用 GetMulti,但单次 key 数别超 100;Memcached 协议限制总请求长度,超限直接拒绝,拆批更稳。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
缓存未命中时 panic?mc.Get() 返回 nil item 不等于 error
mc.Get("user:123") 查不到 key 时,返回的是 (*memcache.Item)(nil),且 err == nil。直接访问 item.Value 就 panic。
正确写法永远是:if item == nil { /* 缓存未命中,查 DB */ },而不是 if err != nil。
封装一层 GetJSON(key string, v interface{}) error 很值得:内部判空 + json.Unmarshal(item.Value, v),统一处理未命中和反序列化错误。
注意 memcache.ErrCacheMiss 只在某些操作(如 Increment)中返回,Get 永远不带这个 error。
真正麻烦的不是连上或存取,而是 key 命名要不要加业务前缀、TTL 设 30 秒还是 2 小时、JSON 序列化要不要忽略空字段——这些决策没法靠库自动做,得贴着你数据库的更新频率和一致性要求来定。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










