这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
图片上传流程
第一版上传:直接存磁盘
“光影”上线第一天,上传接口只有十几行代码:
简单粗暴,图片直接存到 /var/www/photos/。上线第一天我上传了 3 张照片,一切正常。
然后小李来了。
他带着 5 张索尼 A7R5 拍的夜景,每张 8.7 MB。我的 Flask 服务器接收这 5 张图花了 40 秒——因为 Nginx 默认的 client_max_body_size 只有 1MB,我改成了 50MB,但单线程处理大文件依然很慢。
更要命的是,10 个用户同时上传时,服务器的带宽和内存开始告急:
这还没考虑带宽。我的 5Mbps 服务器上行带宽,同时服务上传和下载,直接打满。
第二版上传:流式写入 + 分片
我先优化了上传本身,不把整个文件读入内存:
内存问题缓解了,但带宽问题还在。于是我又加了分片上传支持:
分片解决了大文件上传的问题,但还有一个根本性的问题——所有流量都经过我的服务器。无论怎么优化,上传带宽和存储都是单机的天花板。
第三版上传:客户端直传 OSS
我研究了一圈,发现业界几乎都在用客户端直传对象存储的方案。
核心思路:服务器不碰文件,只负责签发上传凭证。
第一版:客户端 → 我的服务器 → 磁盘
第二版:客户端 → 我的服务器(流式)→ 磁盘
第三版:客户端 → OSS(服务器只签凭证)前端直传 OSS:
对比三版方案
| 指标 | 第一版(磁盘中转) | 第二版(流式分片) | 第三版(直传 OSS) |
|---|---|---|---|
| 服务器带宽消耗 | 上传 + 下载全占 | 上传 + 下载全占 | 几乎为零(只签凭证) |
| 内存占用 | 文件大小 × 并发数 | 极小 | 极小 |
| 支持最大文件 | 受内存限制 | 受磁盘限制 | 5TB(OSS 限制) |
| 断点续传 | ❌ | ✅ | ✅(OSS 分片) |
| 可扩展性 | 单机天花板 | 单机天花板 | 无限(OSS 弹性) |
| 上传速度 | 受服务器带宽限制 | 受服务器带宽限制 | OSS 多线 BGP,极速 |
| 运维复杂度 | 低 | 中 | 中 |
直传 OSS 最大的好处:上传流量完全不走我的服务器。OSS 的带宽是海量的,用户上传 100MB 的 RAW 文件也能在几秒内完成。
安全考量
客户端直传 OSS 后,我需要确保几个安全问题:
还有一个关键问题:用户可能伪造上传回调。解决方案是在 OSS 侧配置回调签名验证: