高并发下载附件:云存储 302 方案为什么比本地流式更扛压
高并发附件下载中,本地 PHP 流式会长期占用 PHP-FPM 工作进程并拖垮站点,云存储 302 仅做权限校验后跳转、由对象存储或 CDN 直发字节,因此更扛压,但需处理签名有效期和防盗链等配置,并可在 Clara BBS 后台系统设置→云存储切换、核对上传限制,切换后复核权限拦截、付费记账和本地附件迁移。
学完这篇你能搞清附件下载的两条链路——本地 PHP 流式输出和云存储 302 跳转——各自的瓶颈在哪,以及为什么后者在并发高峰不容易把站点拖死,并知道在 Clara BBS 里从哪个入口切换。
第一步:先分清两条下载路径到底是什么
用户点「下载附件」,服务器有两种回应方式。
本地流式:PHP 读文件、分块 echo 给浏览器。整个下载过程里,一个 PHP-FPM 工作进程被这个请求占着,直到最后一个字节发完才释放。文件 50MB、用户 4G 慢网,这个进程就被占几十秒。
302 跳转:PHP 只做一件事——校验权限(是否登录、是否购买、会员权益、用户组下载权限),然后返回一个 302,Location 指向对象存储上的临时签名直链。PHP 请求到此结束,进程立刻释放。真正的字节流由阿里云 OSS、腾讯云 COS 这类对象存储直接发给用户浏览器,不经过你的服务器。
一句话区别:本地流式是「你搬」,302 是「你指路,别人搬」。
第二步:本地流式为什么一压就崩
瓶颈不是硬盘,是进程数。假设 PHP-FPM 开了 50 个 worker,第 51 个下载请求就得排队等前面的下完。50 个人同时下 30MB 附件,页面、接口、登录全部跟着卡——因为它们是同一批 worker 在服务。
再叠加三层损耗:PHP 要设 memory_limit 足够大或做分块读、要处理 Range 断点续传、要设长 max_execution_time;下载中途用户关页面,进程还可能空转到超时才发现。带宽也吃紧,出口被下载打满,正常页面请求一起变慢。
注意:宝塔默认
upload_max_filesize/post_max_size只有 2M,本地流式时代这两个值必须调大,但调大只解决「传上来」,不解决「扛并发」。
第三步:302 方案把压力转给了谁
转给三样东西:对象存储的带宽、CDN 的边缘节点、以及你的 PHP 只承担的那一次权限校验(毫秒级)。
结果就是:下载高峰时你的 PHP worker 几乎没被占用,页面照常响应;带宽成本从服务器固定出口变成对象存储按量计费,且可以挂 CDN 摊薄;断点续传、限速、防盗链这些对象存储原生支持,不用自己在 PHP 里写。
代价也要说清楚:签名 URL 有有效期,过期要重新点下载;私有 Bucket 需要正确的签名算法;跨域和防盗链配置错了会 403。
第四步:在 Clara BBS 里切换过去
入口在后台 系统设置 → 云存储,按面板提示填 Bucket、访问域名、密钥等配置,保存即生效,系统无编译缓存、无需清缓存。上传侧也要一并核对 系统设置 → 上传限制,那里分「允许的扩展名」(管图片)和「附件允许的扩展名」(管附件)两个独立字段。
注意:配置完先用一个小附件实测一遍下载全链路,确认 302 后的地址能正常打开、鉴权没过期,再放大文件量。
补充一点:如果你只是偶尔发个大文件、不想占服务器存储,Clara BBS 的附件还支持网盘链接模式——填链接和提取码,不占服务器存储。但它和 302 是两回事:网盘链接模式完全脱离系统鉴权,也拿不到下载统计;302 直链仍然是「系统先验权,云存储再发流」。
第五步:切换后要复核的三件事
- 未登录/未购买用户:确认 302 之前权限真的拦住了,不能只靠「链接不外泄」。
- 付费附件:确认购买记账走通,302 只在购买校验通过后签发。
- 附件管理页:确认已有本地附件是否要迁移,还是继续走本地流式(小文件、低频其实没必要迁)。
注意:本地流式不必彻底废弃。小文件、低频下载、没配云存储的站点,本地流式更简单;真正需要换的是「大文件 + 高并发」这个组合。
小结
- 本地流式的瓶颈是 PHP worker 被长时间占用,并发一高全站跟着卡。
- 302 方案让 PHP 只做权限校验,字节流交给对象存储/CDN,抗压能力来自「进程不被占住」。
- 切换入口在后台「系统设置 → 云存储」,保存即生效;上传白名单在「系统设置 → 上传限制」分两个字段核对。
- 换完必须实测权限拦截、付费校验、大文件下载全链路。
- 网盘链接模式 ≠ 302:前者脱离系统鉴权,后者保留校验与记账。
转载请注明出处,版权归原作者所有。
星耀SVIP
管理员
黑卡会员






