分离部署的价值
织梦默认把图片、附件与程序放在同一台服务器,当文章图片多、访问量大时,静态资源会挤占 PHP、MySQL 的带宽与连接数,导致页面加载变慢、动态请求排队。把图片服务器独立出来,可以让静态与动态各走各的通道,配合 CDN 还能就近回源、降低主站压力,是织梦站点横向扩展的第一步。
架构设计
典型拓扑
- 主站:动态程序 + 数据库,域名
www.example.com。 - 图片服务器:纯 Nginx 静态,域名
img.example.com。 - 同步通道:lsyncd/inotify 实时把主站 uploads 推到图片服务器。
- CDN:回源到 img 服务器,对外提供加速域名。
域名规划
| 用途 | 域名 | 根目录 |
|---|---|---|
| 主站 | www.example.com | /www/wwwroot/dedecms |
| 图片源站 | img-src.example.com | /www/wwwroot/img |
| CDN 域名 | img.example.com | 指向 CDN |
步骤一:搭建图片服务器
在独立机器或独立目录部署 Nginx,仅开放静态访问:
server {
listen 80;
server_name img-src.example.com;
root /www/wwwroot/img;
index index.html;
# 仅放行图片与附件
location ~* \.(jpg|jpeg|png|gif|webp|svg|mp4|pdf|zip)$ {
expires 30d;
add_header Cache-Control "public";
add_header Access-Control-Allow-Origin "https://www.example.com";
}
location / { return 404; }
}
开启 CORS 头部,避免主站用 HTTPS 时图片被浏览器拦截。防盗链 referer 白名单也建议在 Nginx 配置。
步骤二:实时同步附件
主站后台上传图片到 uploads/,需实时同步到图片服务器。推荐 lsyncd + rsync:
# 主站安装 lsyncd
yum install -y lsyncd
# /etc/lsyncd.conf
settings {
logfile="/var/log/lsyncd.log",
statusFile="/var/log/lsyncd.status"
}
sync {
default.rsync,
source="/www/wwwroot/dedecms/uploads/",
target="imguser@10.0.0.9:/www/wwwroot/img/uploads/",
delay=1,
rsync={ binary="/usr/bin/rsync", archive=true, compress=true }
}
配置 SSH 免密钥,启动 systemctl start lsyncd,上传图片后 1 秒内即可在图片服务器看到。
步骤三:修改织梦附件域名
把织梦上传与展示的图片地址替换为图片服务器域名。编辑 data/config.cache.inc.php:
$cfg_multi_site='Y';
$cfg_basehost='https://www.example.com';
$cfg_cmspath='';
$cfg_cookie_encode='...';
// 关键:附件 URL 前缀
$cfg_uploaddir='uploads';
$cfg_image_dir='uploads/allimg';
更彻底的方式是修改 include/helpers/upload.helper.php 中生成 URL 的逻辑,让返回地址带 https://img.example.com/ 前缀;或在模板层用 {dede:global.cfg_img_url/} 占位符,统一在前台拼接。
// 在 common.inc.php 增加
$cfg_img_url='https://img.example.com';
// 模板中
<img src="{dede:global.cfg_img_url/}/uploads/allimg/202407/1.jpg">
步骤四:历史图片迁移
老文章中的图片地址仍是相对路径,需要批量更新数据库:
-- 把 body 中 /uploads 替换为图片域名
UPDATE dede_addonarticle
SET body=REPLACE(body, 'src="/uploads', 'src="https://img.example.com/uploads')
WHERE body LIKE '%/uploads%';
-- 同样处理 litpic 缩略图字段
UPDATE dede_archives
SET litpic=CONCAT('https://img.example.com', litpic)
WHERE litpic LIKE '/uploads%' AND litpic <> '';
执行前先备份,执行后重新生成静态页验证图片显示。
步骤五:接入 CDN
CDN 回源到 img-src.example.com,对外域名 img.example.com。在 CDN 控制台:
- 添加域名,源站填图片服务器 IP 或域名。
- 回源协议 HTTPS,端口 443。
- 缓存规则:图片类缓存 30 天,状态码 404 缓存 1 分钟。
- HTTPS:申请免费证书并配置到 CDN。
- 刷新:图片更新后调用 API 刷新对应 URL。
注意事项
- 图片服务器与主站务必同源协议,避免混合内容警告。
- 同步通道要做监控,lsyncd 失败要告警,避免新图不同步。
- 历史数据迁移的 SQL 要先在测试库验证正则。
- 防盗链白名单加上搜索引擎与友站,避免误伤。
- 定期校验主站与图片服务器文件数与大小是否一致。
建议与展望
图片分离只是横向扩展起点,建议后续把图片服务器升级为对象存储(OSS/S3),彻底摆脱单机磁盘与同步通道,实现无限容量与跨区域加速。同时把“上传—同步—CDN刷新”串成监控看板,新文章发布后图片秒级可达。让织梦静态资源具备与主流云原生方案同等的扩展能力,从容应对未来流量增长。