织梦图片服务器分离部署教程

把图片流量从主站剥离,提升并发与缓存命中率

分离部署的价值

织梦默认把图片、附件与程序放在同一台服务器,当文章图片多、访问量大时,静态资源会挤占 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刷新”串成监控看板,新文章发布后图片秒级可达。让织梦静态资源具备与主流云原生方案同等的扩展能力,从容应对未来流量增长。