关于附件的云存储
之前我们用的加速方案一直是通过七牛云去源站爬取附件存储,这样虽然能达到用 CDN 加速的效果,但附件会存有两份:一份在我的服务器,一份在七牛云那边。
其实之前我们一直用的是 PHP 代理上传模式,但如果改用浏览器直传 OSS 模式,我觉得这才是最优解。至少从服务器的带宽并发、上传速度等方面来看,都有很大的优势。
所以后期我们可以尝试用浏览器直传 OSS,把文件传到云端再去做加速。这才是最优方案,特别是针对附件多、附件大的场景。(其实我们用的场景更多是图片上传以及保存。这种场景的话,虽然说附件不大,但是如果日积月累,这也是一个不小的存储压力)


PHP 代理上传的优点
PHP 代理并不是错误方案,它有几个明显优点。
1. 更容易控制上传文件
当前 PHP 可以在上传前检查:
- 文件最大 200 MB。
- 文件是否上传完整。
- 用户是否已经登录。
- 上传目标是否为合法 OSS 域名。
未来还可以加入:
- 视频真实格式检测。
- 病毒扫描。
- 视频时长检查。
- 用户上传额度检查。
2. 不需要处理 OSS CORS
浏览器直接访问 OSS 属于跨域请求,OSS 必须配置允许你的域名上传。
PHP 代理上传时,浏览器只访问自己的 PHP 域名,因此不受 OSS CORS 限制。
3. 服务端能够确认上传真的完成
PHP 自己把文件上传到 OSS,因此它明确知道上传结果。
PHP 代理上传的问题
1. PHP 服务器承担整个视频流量
假设用户上传一个 100 MB 视频:
<span><span>用户 → PHP:100 MB</span> <span>PHP → OSS:100 MB</span></span>
PHP 服务器需要接收、临时保存、再发送整个文件。
如果同时有 20 个用户上传 200 MB 视频,服务器可能需要处理约 4 GB 的上传数据,并保持大量长连接。
2. 容易受到 PHP 配置限制
当前代理上传依赖这些配置:
<span><span>upload_max_filesize = 210M</span> <span>post_max_size = 210M</span> <span>max_execution_time = 600</span> <span>max_input_time = 600</span></span>
还会受以下因素影响:
- Nginx client_max_body_size
- PHP-FPM 超时
- 服务器临时磁盘容量
- 服务器公网带宽
- CDN、WAF 或反向代理限制
3. 可能产生服务器公网出流量费用
如果 PHP 服务器不是广州阿里云 ECS,或者上传 OSS 时使用公网 Endpoint,PHP 向 OSS 转发视频可能产生服务器公网出流量费用。
即使不收费,也会占用服务器带宽,影响其他 API 请求。
浏览器直传的优点
1. PHP 不再搬运视频
PHP 只需要处理几个很小的 JSON 请求:
<span><span>获取上传签名</span> <span>提交 ASR</span> <span>查询任务状态</span></span>
因此服务器可以用更低配置,同时承载更多用户。
2. 更适合大文件和高并发
用户直接连接 OSS,上传能力由 OSS 承担。OSS 对大文件、高并发上传和分片上传的支持远强于普通 PHP 服务器。
3. 上传通常更快、更稳定
用户到 OSS 只经过一次传输,不需要等待 PHP 接收完成后再次转发。
浏览器直传的风险
1. 必须配置 OSS CORS
需要在 OSS Bucket 配置类似规则:
<span><span>来源:你的正式域名、测试域名</span> <span>允许方法:PUT、POST、HEAD</span> <span>允许请求头:Content-Type</span> <span>暴露响应头:ETag</span></span>
不建议正式环境长期使用:
<span><span>AllowedOrigin: *</span></span>
2. 当前预签名 PUT 无法很好限制文件大小
你现在生成的是预签名 PUT URL。它能够限制上传路径和 Content-Type,但无法像服务端代理一样方便地强制限制文件最大 200 MB。
更完善的方案是使用:
- OSS 表单直传 Policy。
- Policy 中配置 content-length-range。
- 或上传完成后,由 PHP 查询 OSS 文件大小,不符合要求立即删除。
3. 需要处理垃圾文件
用户可能拿到上传 URL,上传完成后直接关闭网页,没有提交 ASR。
这些文件不会对应正常任务记录,需要通过 OSS 生命周期规则或定时任务清理:
<span><span>uploads/ 下超过 24 小时的文件自动删除</span></span>
4. 不能直接信任前端提交的 oss_key
浏览器可能伪造一个 OSS Key,然后请求 ASR。
服务端在提交 ASR 前应验证:
- OSS Key 是否由当前用户申请。
- 文件是否真实存在。
- 文件大小是否符合限制。
- 文件路径是否属于当前用户或当前上传任务。
- 文件是否已经处理过。