Go文件缓存分内存层(map+sync.RWMutex或第三方库)和HTTP层(ETag/Last-Modified/Cache-Control),协同降低IO压力与带宽消耗;内存缓存适用于中小规模静态文件,需配合过期清理与写时失效。
用 Go 实现文件缓存,核心是分两层:内存中快速读取热数据(如 map + sync.RWMutex 或第三方库),再配合 HTTP 协议级缓存(如 ETag、Last-Modified、Cache-Control)减少重复传输。两者结合,既降低磁盘/IO压力,又节省带宽、提升响应速度。
适合中小规模、读多写少的静态文件(如配置模板、小图标、JSON Schema)。不建议缓存大文件(如 >10MB),避免内存溢出。
sync.Map 或带读写锁的 map[string][]byte 存储文件路径 → 内容字节切片time.AfterFunc 为每个条目设延迟清理github.com/patrickmn/go-cache 或 github.com/bluele/gcache 等成熟封装关键不是“服务端存不存”,而是告诉浏览器/代理“什么时候可以复用旧响应”。Go 的 http.ServeFile 默认不设缓存头,需手动补充。
Cache-Control: public, max-age=3600(1 小时可复用)ETag(内容哈希)或 Last-Modified(文件修改时间),在 GET 请求带 If-None-Match 或 If-Modified-Since 时,返回 304 Not Modified
http.FileServer 包裹自定义 FileSystem,重写 Open 方法,在 http.File 返回前写入缓存头和 ETag
若文件可能被外部进程修改(非 Go 应用写入),务必用 os.Stat().ModTime() 或 md5.Sum(fileBytes) 动态生成 ETag,不能硬编码
内存缓存加速服务端读取,HTTP 缓存减少网络往返——二者正交,可同时启用。
fmt.Sprintf("%x", md5.Sum(content)))If-None-Match,匹配则直接写 304,不读磁盘也不传正文200 响应,附上 ETag 和 Cache-Control 头基本上就这些。不需要复杂框架,标准库 + 少量逻辑就能搭出高效文件缓存。重点是理清“谁在什么环节决定是否走缓存”——内存层管服务端效率,HTTP 层管客户端行为,各司其职。