为什么把附件迁到 OSS
织梦默认把图片、文档、压缩包等附件存在服务器本地 uploads/ 目录。随着内容增长,本地磁盘容量、IOPS、带宽都会成为瓶颈,迁移服务器时要搬运海量小文件,备份恢复也极慢。OSS 对象存储具备无限容量、按量付费、自带 CDN 加速、跨区域复制等优势,把附件搬到 OSS 后,织梦主站只保留程序与数据库,运维复杂度大幅下降。
方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| 本地磁盘 | 简单 | 容量受限、迁移难 |
| OSS 直传 | 无限容量、CDN 加速 | 需改造上传逻辑 |
| OSS + 回源 | 兼容老 URL | 需 Nginx 配置 |
| NAS 挂载 | 无需改代码 | 成本高、单点风险 |
步骤一:创建 OSS Bucket
在阿里云 OSS 控制台创建 Bucket,建议与 ECS 同区域,通过内网访问免流量费。
- Bucket 名称:
dede-attachments - 区域:与服务器一致(如华东1杭州)
- 读写权限:私有(通过签名访问)或公共读
- 创建 RAM 子账号,授予
oss:PutObject、oss:GetObject权限,记录 AccessKey 与 Secret。
步骤二:引入 OSS SDK
下载阿里云 OSS PHP SDK 到 include/oss/ 目录,或用 composer 安装:
composer require aliyuncs/oss-sdk-php
新建配置文件 data/oss.config.php:
<?php
$oss_config=[
'accessKeyId'=> 'LTAI5txxxx',
'accessKeySecret'=> 'AbcdEFxxxx',
'endpoint'=> 'oss-cn-hangzhou-internal.aliyuncs.com',
'bucket'=> 'dede-attachments',
'cdnDomain'=> 'https://img.example.com', // CDN 域名
'prefix'=> 'uploads/', // OSS 内目录前缀
];
?>
步骤三:改造上传逻辑
在 include/helpers/upload.helper.php 增加上传到 OSS 的方法,替换原 move_uploaded_file:
require_once DEDEINC.'/oss/autoload.php';
use OSS\OssClient;
function upload_to_oss($localFile, $object) {
global $oss_config;
$oss=new OssClient(
$oss_config['accessKeyId'],
$oss_config['accessKeySecret'],
$oss_config['endpoint']
);
$object=$oss_config['prefix'] . $object;
$oss->uploadFile($oss_config['bucket'], $object, $localFile);
return $oss_config['cdnDomain'] . '/' . $object;
}
// 在原上传成功后调用
$ossUrl=upload_to_oss($tmpName, $savePath);
// 把 $ossUrl 写入数据库的 url 字段
上传完成后可保留本地副本做备份,也可立即删除本地文件节省空间;建议先双写一段时间,验证稳定后再切纯 OSS。
步骤四:展示与回源
方案 A:模板直接用 CDN 域名
数据库存的就是 https://img.example.com/uploads/xxx.jpg,前台直接渲染即可。
方案 B:保留相对路径,Nginx 回源
不想改数据库时,让 Nginx 把 /uploads/ 反代到 OSS:
location /uploads/ {
proxy_pass https://dede-attachments.oss-cn-hangzhou.aliyuncs.com/uploads/;
proxy_set_header Host dede-attachments.oss-cn-hangzhou.aliyuncs.com;
expires 30d;
}
这样老文章图片 URL 不变,但实际从 OSS 读取。
步骤五:历史附件迁移
用 ossutil 批量上传老附件到 OSS:
# 安装 ossutil 后配置 AK
ossutil config
# 同步整个 uploads 目录,多线程
ossutil cp /www/wwwroot/dedecms/uploads/ \
oss://dede-attachments/uploads/ \
-r --jobs 10 --parallel 10 \
--exclude "*.php" --exclude "*.html"
# 校验文件数
find /www/wwwroot/dedecms/uploads -type f | wc -l
ossutil ls oss://dede-attachments/uploads/ | tail -1
注意事项
- AccessKey 一定用 RAM 子账号,切勿用主账号 AK。
- Bucket 公共读要配防盗链,避免流量被盗刷。
- 开启 OSS 版本控制,误删文件可恢复。
- 配置生命周期,老附件自动转低频/归档存储降本。
- 数据库备份要包含附件 URL 映射,便于回溯。
建议与后续
建议把 OSS 接入做成织梦的独立插件,提供“本地/OSS/混合”三档开关,方便在不同环境切换。把上传成功率、OSS 延迟接入监控告警,单次上传超过 3 秒即报警。同时规划冷热数据分层,热图走 CDN,归档图转 OSS-Archive,让存储成本随内容生命周期自然下降,构建可持续扩展的织梦附件体系。