织梦附件存放到oss对象存储

告别本地磁盘瓶颈,让织梦附件走向海量可扩展存储

为什么把附件迁到 OSS

织梦默认把图片、文档、压缩包等附件存在服务器本地 uploads/ 目录。随着内容增长,本地磁盘容量、IOPS、带宽都会成为瓶颈,迁移服务器时要搬运海量小文件,备份恢复也极慢。OSS 对象存储具备无限容量、按量付费、自带 CDN 加速、跨区域复制等优势,把附件搬到 OSS 后,织梦主站只保留程序与数据库,运维复杂度大幅下降。

方案对比

方案优点缺点
本地磁盘简单容量受限、迁移难
OSS 直传无限容量、CDN 加速需改造上传逻辑
OSS + 回源兼容老 URL需 Nginx 配置
NAS 挂载无需改代码成本高、单点风险

步骤一:创建 OSS Bucket

在阿里云 OSS 控制台创建 Bucket,建议与 ECS 同区域,通过内网访问免流量费。

  • Bucket 名称:dede-attachments
  • 区域:与服务器一致(如华东1杭州)
  • 读写权限:私有(通过签名访问)或公共读
  • 创建 RAM 子账号,授予 oss:PutObjectoss: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,让存储成本随内容生命周期自然下降,构建可持续扩展的织梦附件体系。