go上传后需立即压缩图片:必须在写入磁盘前完成,避免额外i/o和并发冲突;须按格式分发编码器(jpeg/png/webp),校验魔数与mime限制类型,解码前获取尺寸防失真,失败时立即清理临时文件防磁盘占满。

上传后立刻压缩图片,别等用户等得不耐烦
Go 的 http.FileServer 或 multipart.FormFile 读取完文件后,必须在写入磁盘前完成压缩——否则多一次 I/O,延迟翻倍,还可能因并发写入冲突导致文件损坏。压缩逻辑要塞进上传 handler 的主流程里,不能丢给 goroutine 异步处理(除非你有可靠的队列和状态回传机制)。
- 用
image.Decode读原始图时,务必检查io.EOF和格式错误,JPEG/PNG/WebP 都可能返回不同 error - 压缩前先用
image.Config获取宽高,避免盲目缩放——比如用户上传 100×100 小图,再压到 80% 就失真了 - WebP 格式在 Go 原生
image包中不支持编码,得引入golang.org/x/image/webp,且需手动调用webp.Encode
用 resize 库控制质量与尺寸,别只靠 jpeg.EncodeQuality
golang.org/x/image/draw 自带的缩放能力太基础,模糊、锯齿明显;真正生产用得上的是 github.com/nfnt/resize 或 github.com/disintegration/imaging。前者轻量但只支持 nearest/bilinear/bicubic 插值,后者自带裁切、旋转、高质量压缩链路。
-
resize.Resize默认用 bicubic,适合人像;imaging.Resize默认是 lanczos,锐度更高但略慢 - 质量参数不是百分比:jpeg 是 0–100 整数,png 是 0–9 压缩级别,webp 是 0–100(注意:值越小越糊,但文件越小)
- 别对 PNG 强行设
jpeg.EncodeQuality——会 panic,得按格式分 dispatch:jpeg →jpeg.Encode,png →png.Encode,webp →webp.Encode
上传+压缩失败时,必须删临时文件,否则磁盘悄悄爆掉
Go 的 os.Create 和 os.OpenFile 返回的 *os.File 必须显式 Close(),但更关键的是:只要压缩中途出错(比如内存不足、格式不支持),已写入的临时文件就得 os.Remove。否则几十次失败后,/tmp 占满,整个服务卡死。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 用
defer不够——它只在函数 return 时触发,而错误可能发生在中间某步;推荐用err != nil分支里立即os.Remove(tmpPath) - 别依赖
filepath.Join(os.TempDir(), ...)存原图——TempDir 可能被清理,建议固定路径如/var/tmp/uploads并配 logrotate - 如果用了
multipart.File的Seek(0, io.SeekStart)多次读取,记得每次读完都Seek(0, io.SeekStart)回位,否则第二次Decode读空
并发上传时,别让 image.Decode 吃光内存
一张 20MB 的 TIFF 或高清 RAW 图,image.Decode 解码后可能占 200MB 内存。10 个并发上传就直接 OOM。必须加内存限制和格式白名单。
- 上传前用
mimeType和魔数(前 4 字节)校验:只允许image/jpeg、image/png、image/webp,拒绝image/tiff、image/heic - 用
http.MaxBytesReader包裹 request body,比如限 10MB:http.MaxBytesReader(w, r, 10 - 解码时用
image.DecodeConfig先拿宽高,超 5000×5000 就直接 reject,避免解码大图
最易被忽略的点:压缩后的文件名要不要保留原始扩展名?要。但 WebP 图片如果原图是 .jpg,压缩后存成 .webp,前端引用时 MIME 类型必须同步改成 image/webp,否则浏览器当 JPEG 解析会报错。这个 header 和路径得一起改,不能只换后缀。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










