天天看點

Discuz 論壇附件、頭像等資源遷移到阿裡雲 OSS 并開啟 CDN 的解決方案

本文首發 http://zhaoda.net/2018/05/23/discuz-attachment-oss/ 轉載請注明出處

Discuz 論壇的附件、頭像等資源不斷增長,如果和主程式一起存儲在雲伺服器上,就會導緻雲盤要定期進行擴容操作;附件如果需要進行 CDN 加速也隻能使用回源政策進行 CDN 配置。為了一勞永逸的解決附件存儲和加速問題,将附件等資源遷移到對象存儲服務上是一個好的選擇,本文以阿裡雲 ECS、OSS 服務為背景,其他雲計算平台也可以參考。

建立 OSS Bucket

  • OSS 管理頁面分别給論壇附件、頭像建立 Bucket,名稱為

    img-bucket

    avatar-bucket

    (如果自定為其他名字,後文提到的 Bucket 名稱請自行替換),

    區域

    選擇和論壇所在雲伺服器 ESC 一緻的區域,記錄下該區域的

    Endpoint

    存儲類型

    選擇标準存儲,

    讀取權限

    選擇私有
  • 通路控制 建立網站使用者,生成

    AccessKey

    AccessKeySecret

    ,給該使用者授權

    AliyunOSSFullAccess

開啟 CDN

  • 到剛建立好的 Bucket 的域名管理中綁定使用者域名,比如

    img.example.com

    avatar.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 name

    AccessKey

    AccessKeySecret

    :

    連接配接後填寫到

    /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 論壇附件、頭像等資源遷移到阿裡雲 OSS 并開啟 CDN 的解決方案
  • 到論壇背景 -> 站長 -> UCenter 設定 中修改頭像調用方式為

    使用靜态位址調用頭像

Discuz 論壇附件、頭像等資源遷移到阿裡雲 OSS 并開啟 CDN 的解決方案
  • 由于有使用者沒有上傳頭像而使用預設頭像,到

    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

  • 域名管理中添加域名

    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 檔案 URL

      CSS 檔案 URL

      自定義 URL

      并填寫 CDN 位址

      http://static.example.com/data/cache/

Discuz 論壇附件、頭像等資源遷移到阿裡雲 OSS 并開啟 CDN 的解決方案

小雲 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.php

    cdndomain

    的值為

    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]( https://help.aliyun.com/document_detail/32190.html?spm=a2c4g.11186623.6.1061.3oclSk ) 工具綁定 OSS,然後 開啟論壇遠端附件方式 來将附件接入 OSS 和 CDN;但是這些方案都沒有本文的方案更具有通用性和易用性

參考