Discuz 论坛附件、头像等资源迁移到阿里云 OSS 并开启 CDN 的解决方案

本文涉及的产品
对象存储 OSS,标准 - 本地冗余存储 20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000 次 1年
简介: Discuz 论坛的附件、头像等资源不断增长,如果和主程序一起存储在云服务器上,就会导致云盘要定期进行扩容操作;附件如果需要进行 CDN 加速也只能使用回源策略进行 CDN 配置。为了一劳永逸的解决附件存储和加速问题,将附件等资源迁移到对象存储服务上是一个好的选择,本文以阿里云 ECS、OSS 服务为背景,其他云计算平台也可以参考。

本文首发 http://zhaoda.net/2018/05/23/discuz-attachment-oss/
转载请注明出处

Discuz 论坛的附件、头像等资源不断增长,如果和主程序一起存储在云服务器上,就会导致云盘要定期进行扩容操作;附件如果需要进行 CDN 加速也只能使用回源策略进行 CDN 配置。为了一劳永逸的解决附件存储和加速问题,将附件等资源迁移到对象存储服务上是一个好的选择,本文以阿里云 ECS、OSS 服务为背景,其他云计算平台也可以参考。

创建 OSS Bucket

  • OSS 管理页面分别给论坛附件、头像创建 Bucket,名称为 img-bucketavatar-bucket(如果自定为其他名字,后文提到的 Bucket 名称请自行替换),区域选择和论坛所在云服务器 ESC 一致的区域,记录下该区域的 Endpoint存储类型选择标准存储,读取权限选择私有
  • 访问控制 创建网站用户,生成 AccessKeyAccessKeySecret,给该用户授权 AliyunOSSFullAccess

开启 CDN

  • 到刚创建好的 Bucket 的域名管理中绑定用户域名,比如img.example.comavatar.example.com
  • 勾选阿里云 CDN 加速,如果域名 dns 解析在阿里云,可以勾选自动添加 CNAME 记录,如果不在请自行添加域名的cname阿里云 CDN 加速域名
  • 勾选CDN 缓存自动刷新
  • 建议单独为 CDN 申请单独的根域名,这样 CDN 请求不会带上网站的 cookie 等信息
  • CDN 域名管理中对新创建的域名进行配置
    • 开启私有Bucket回源
    • 缓存过期时间添加规则,内容目录/过期时间为3年,权重99
    • 设置HTTP头添加规则,Cache-Control 设置为 max-age=315360000
    • 开启智能压缩
    • 其他设置请根据实际需求自行修改

迁移附件和头像

  • 安装 ossfs,该工具能让您在 Linux 系统中把 OSS Bucket 挂载到本地文件系统中

ossfs 基于s3fs 构建,具有s3fs 的全部功能。主要功能包括

  • 支持POSIX 文件系统的大部分功能,包括文件读写,目录,链接操作,权限,uid/gid,以及扩展属性(extended attributes)
  • 通过OSS 的multipart 功能上传大文件
  • MD5 校验保证数据完整性
# 下载并安装
wget http://docs-aliyun.cn-hangzhou.oss.aliyun-inc.com/assets/attach/32196/cn_zh/1524809958556/ossfs_1.80.4_centos7.0_x86_64.rpm?spm=a2c4g.11186623.2.6.XJB3Dd&file=ossfs_1.80.4_centos7.0_x86_64.rpm
mv ossfs_1.80.4_centos7.0_x86_64.rpm?spm=a2c4g.11186623.2.6.QwMtDE ossfs_1.80.4_centos7.0_x86_64.rpm
yum localinstall ossfs_1.80.4_centos7.0_x86_64.rpm
  • 将每个 bucket nameAccessKeyAccessKeySecret:连接后填写到 /etc/passwd-ossfs,每行一个,并设置文件权限为 640
img-bucket:AccessKey:AccessKeySecret
my-bucket:AccessKey:AccessKeySecret
chmod 640 /etc/passwd-ossfs
  • 安装 mailcap,解决 bucket 中的文件 Content-Type 全是 application/octet-stream 的问题
yum install mailcap
  • 将论坛附件和头像剪切到其他临时目录
# 假设论坛根目录为 /data/htdocs/www ,后续脚本将以此为准,请根据实际情况修改
mv /data/htdocs/www/data/attachment /data/
mv /data/htdocs/www/uc_server/data/avatar /data/
  • 挂载 OSS Bucket
# 重新创建被剪的目录
mkdir /data/htdocs/www/data/attachment
mkdir /data/htdocs/www/uc_server/data/avatar

# 获取运行 php-fpm 和 nginx 的系统用户 uid 和 gid,比如 www 用户
# uid=1000(www) gid=1000(www) 组=1000(www)
id www

# 挂载 bucket
# Endpoint:请使用内网地址,速度快且流量免费
# -o noxattr:如果你没有使用eCryptFs等需要XATTR的文件系统,可以提升性能
# -o kernel_cache:使用文件系统的 page cache
# -o allow_other:允许其他用户访问挂载文件夹
# -ouid -ogid:制定挂载目录的用户和组权限
ossfs img-bucket /data/htdocs/www/data/attachment -ourl=Endpoint -o noxattr -o kernel_cache -o allow_other -ouid=1000 -ogid=1000
ossfs avatar-bucket /data/htdocs/www/uc_server/data/avatar -ourl=Endpoint -o noxattr -o kernel_cache -o allow_other -ouid=1000 -ogid=1000
  • 复制附件、头像到 bucket
cp -rf /data/attachment/* /data/htdocs/www/data/attachment
cp  -rf /data/avatar/* /data/htdocs/www/uc_server/data/avatar
# 到 oss bucket 文件管理验证数据没有问题后可以删除临时拷贝
rm -rf /data/attachment/
rm -rf /data/avatar/
  • 如何卸载 bucket
# root用户
umount /data/htdocs/www/data/attachment
umount /data/htdocs/www/uc_server/data/avatar
# 非root用户
fusermount -u /data/htdocs/www/data/attachment
fusermount -u /data/htdocs/www/uc_server/data/avatar
  • 开机启动,以 CentOS 7.0 为例,其他系统参考 FAQ
# 根据下面的模板创建启动脚本
vi /etc/init.d/ossfs
# 添加执行权限
chmod a+x /etc/init.d/ossfs
# 设置开机启动
chkconfig ossfs on
#! /bin/bash
#
# ossfs      Automount Aliyun OSS Bucket in the specified direcotry.
#
# chkconfig: 2345 90 10
# description: Activates/Deactivates ossfs configured to start at boot time.

ossfs img-bucket /data/htdocs/www/data/attachment -ourl=Endpoint -o noxattr -o kernel_cache -o allow_other -ouid=1000 -ogid=1000
ossfs avatar-bucket /data/htdocs/www/uc_server/data/avatar -ourl=Endpoint -o noxattr -o kernel_cache -o allow_other -ouid=1000 -ogid=1000

修改论坛附件和头像地址

  • 到论坛后台 -> 全局 -> 上传设置 -> 基本设置 中修改 本地附件 URL 地址

discuz_attachment_url

  • 到论坛后台 -> 站长 -> UCenter 设置 中修改头像调用方式为使用静态地址调用头像

discuz_avatar_url

  • 由于有用户没有上传头像而使用默认头像,到 avatar bucket 的根目录添加3个默认头像文件 noavatar_big.gif、noavatar_middle.gif 和 noavatar_small.gif
  • 修改source/function/function_core.php中头像地址
// 查找下面的代码并修改
// $file = $ucenterurl.'/data/avatar/'.$dir1.'/'.$dir2.'/'.$dir3.'/'.substr($uid, -2).($real ? '_real' : '').'_avatar_'.$size.'.jpg';
// return $returnsrc ? $file : '<img src="'.$file.'" onerror="this.onerror=null;this.src=\''.$ucenterurl.'/images/noavatar_'.$size.'.gif\'" />';
// 使用头像cdn地址
$cdnurl = 'http://avatar.example.com/';
$file = $cdnurl.$dir1.'/'.$dir2.'/'.$dir3.'/'.substr($uid, -2).($real ? '_real' : '').'_avatar_'.$size.'.jpg';
return $returnsrc ? $file : '<img src="'.$file.'" onerror="this.onerror=null;this.src=\''.$cdnurl.'noavatar_'.$size.'.gif\'" />';
  • 修改uc_server/avatar.php中头像重定向地址
$avatar = './data/avatar/'.get_avatar($uid, $size, $type);
if(file_exists(dirname(__FILE__).'/'.$avatar)) {
   
    if($check) {
   
        echo 1;
        exit;
    }
    $random = !empty($random) ? rand(1000, 9999) : '';
  // rewrite avatar url
  $avatar = 'http://avatar.example.com/'.substr($avatar, 14);
  $avatar_url = empty($random) ? $avatar : $avatar.'?random='.$random;
} else {
   
    if($check) {
   
        echo 0;
        exit;
    }
    $size = in_array($size, array('big', 'middle', 'small')) ? $size : 'middle';
  // $avatar_url = 'images/noavatar_'.$size.'.gif';
  // rewrite avatar url
  $avatar_url = 'http://avatar.example.com/noavatar_'.$size.'.gif';
}

if(empty($random)) {
   
    header("HTTP/1.1 301 Moved Permanently");
    header("Last-Modified:".date('r'));
    header("Expires: ".date('r', time() + 86400));
}

// header('Location: '.UC_API.'/'.$avatar_url);
header('Location: '.$avatar_url);

论坛 JS、CSS、样式图片等资源接入 CDN

  • CDN 域名管理中添加域名 static.example.com
  • 回源设置中源站信息类型选择IP,并填写源站地址IP为论坛外网 ip,端口 80
  • 其他缓存和 HTTP 头设置参考上面 OSS Bucket 的 CDN 设置
  • 添加论坛 Nginx 的 vhost 配置,如果是其他 web server 请参考添加
server
{
    listen    80;
    server_name static.example.com;

    index index.html index.htm;
    root  /data/htdocs/www;
    # error_page  404 = /topic-1.html;
    expires max;

    location ~ /\.git
    {
        return 404;
    }

    location ~ ^/.*\.(php|php5)$
    {
        deny all;
    }

    access_log  off;
}
    • 到论坛后台 -> 全局 -> 性能优化 -> 服务器优化 中修改 JS 文件 URLCSS 文件 URL自定义 URL 并填写 CDN 地址 http://static.example.com/data/cache/

discuz_static_url

小云 APP 缩略图接入 CDN

  • 如果论坛使用小云 APP 开发了客户端程序,且开启了生成缩略图功能,同样可以参照上面附件、头像的方式接入 OSS 和 CDN
  • 创建 thumb bucket 并开启 CDN 加速域名 thumb.example.com
  • 用 ossfs 将 /data/htdocs/www/data/appbyme/thumb 目录挂载到 thumb bucket,并将已有缩略图拷贝进去
  • 复制一份 /data/htdocs/www/mobcent/app/config/mobcent.php/data/htdocs/www/mobcent/app/config/my_mobcent.php
  • 修改 my_mobcent.phpcdndomain 的值为 thumb.example.com
  • 修改 /data/htdocs/www/mobcent/app/components/web/ImageUtils.php 中缩略图地址
private static function _getThumbUrlFile($image, $thumb) {
   
    //支持自定义CDN域名
    $cacheurl = Yii::app()->params['mobcent']['cache']['cdndomain'];
    if(empty($cacheurl)){
   
        $cacheurl = Yii::app()->getController()->dzRootUrl;
    }
    // return sprintf('%s/%s/%s/%s_%s', 
    //     $cacheurl,
    //     MOBCENT_THUMB_URL_PATH,
    //     self::_getThumbTempPath($image),
    //     (isset($_GET['sdkVersion']) && $_GET['sdkVersion'] > '1.0.0') ? 'xgsize' : 'mobcentSmallPreview',
    //     $thumb
    // );
    // 修改缩略图地址
    return sprintf('%s/%s/%s_%s', 
        $cacheurl,
        self::_getThumbTempPath($image),
        (isset($_GET['sdkVersion']) && $_GET['sdkVersion'] > '1.0.0') ? 'xgsize' : 'mobcentSmallPreview',
        $thumb
    );
}

后记

  • 至此,Discuz 论坛全站资源、附件、头像都接入了 OSS 和 CDN,将降低论坛主服务器 http 请求量压力并提高页面打开速度
  • 除了本文使用的 ossfs 方案将附件接入 OSS,还有一些其他方案将附件接入 OSS 或 CDN;比如最简单的 CDN 回源方式将附件接入 CDN;还可以通过 ossftp 工具绑定 OSS,然后开启论坛远程附件方式来将附件接入 OSS 和 CDN;但是这些方案都没有本文的方案更具有通用性和易用性

参考

目录
相关文章
|
1月前
|
存储 人工智能 Cloud Native
阿里云渠道商:OSS与传统存储系统的差异在哪里?
本文对比传统存储与云原生对象存储OSS的架构差异,涵盖性能、成本、扩展性等方面。OSS凭借高持久性、弹性扩容及与云服务深度集成,成为大数据与AI时代的优选方案。
|
3月前
|
存储 缓存 网络协议
如何使用CDN加速访问OSS存储的图片资源?
通过阿里云CDN加速OSS上的图片和视频资源,可显著提升访问速度、降低带宽成本。CDN将静态资源缓存至离用户最近的节点,减少加载时间,并提供图像处理、缓存优化等功能,提升用户体验。同时,CDN还支持访问数据分析,助力运营决策。本文详解如何通过CDN控制台配置OSS加速,包括添加域名、设置CNAME、配置缓存策略等步骤,帮助您快速实现资源加速。
|
3月前
|
存储 运维 安全
阿里云国际站OSS与自建存储的区别
阿里云国际站对象存储OSS提供海量、安全、低成本的云存储解决方案。相比自建存储,OSS具备易用性强、稳定性高、安全性好、成本更低等优势,支持无限扩展、自动冗余、多层防护及丰富增值服务,助力企业高效管理数据。
|
3月前
|
存储 域名解析 前端开发
震惊!不买服务器,还可以用阿里云国际站 OSS 轻松搭建静态网站
在数字化时代,利用阿里云国际站OSS可低成本搭建静态网站。本文详解OSS优势及步骤:创建Bucket、上传文件、配置首页与404页面、绑定域名等,助你快速上线个人或小型业务网站,操作简单,成本低廉,适合初学者与中小企业。
|
5月前
|
编解码 监控 算法
CDN+OSS边缘加速实践:动态压缩+智能路由降低30%视频流量成本(含带宽峰值监控与告警配置)
本方案通过动态压缩、智能路由及CDN与OSS集成优化,实现视频业务带宽成本下降31%,首帧时间缩短50%,错误率降低53%。结合实测数据分析与架构创新,有效解决冷启动延迟、跨区域传输及设备适配性问题,具备快速投入回收能力。
362 0
|
机器学习/深度学习 人工智能 专有云
人工智能平台PAI使用问题之怎么将DLC的数据写入到另一个阿里云主账号的OSS中
阿里云人工智能平台PAI是一个功能强大、易于使用的AI开发平台,旨在降低AI开发门槛,加速创新,助力企业和开发者高效构建、部署和管理人工智能应用。其中包含了一系列相互协同的产品与服务,共同构成一个完整的人工智能开发与应用生态系统。以下是对PAI产品使用合集的概述,涵盖数据处理、模型开发、训练加速、模型部署及管理等多个环节。
|
9月前
|
SQL 分布式计算 Serverless
基于阿里云 EMR Serverless Spark 版快速搭建OSS日志分析应用
基于阿里云 EMR Serverless Spark 版快速搭建OSS日志分析应用
241 0
|
存储 人工智能 缓存
AI助理直击要害,从繁复中提炼精华——使用CDN加速访问OSS存储的图片
本案例介绍如何利用AI助理快速实现OSS存储的图片接入CDN,以加速图片访问。通过AI助理提炼关键操作步骤,避免在复杂文档中寻找解决方案。主要步骤包括开通CDN、添加加速域名、配置CNAME等。实测显示,接入CDN后图片加载时间显著缩短,验证了加速效果。此方法大幅提高了操作效率,降低了学习成本。
5878 16
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。