本文首發 http://zhaoda.net/2018/05/23/discuz-attachment-oss/ 轉載請注明出處
Discuz 論壇的附件、頭像等資源不斷增長,如果和主程式一起存儲在雲伺服器上,就會導緻雲盤要定期進行擴容操作;附件如果需要進行 CDN 加速也隻能使用回源政策進行 CDN 配置。為了一勞永逸的解決附件存儲和加速問題,将附件等資源遷移到對象存儲服務上是一個好的選擇,本文以阿裡雲 ECS、OSS 服務為背景,其他雲計算平台也可以參考。
建立 OSS Bucket
- 在 OSS 管理頁面分别給論壇附件、頭像建立 Bucket,名稱為
和img-bucket
(如果自定為其他名字,後文提到的 Bucket 名稱請自行替換),avatar-bucket
選擇和論壇所在雲伺服器 ESC 一緻的區域,記錄下該區域的區域
,Endpoint
選擇标準存儲,存儲類型
選擇私有讀取權限
- 到 通路控制 建立網站使用者,生成
AccessKey
,給該使用者授權AccessKeySecret
AliyunOSSFullAccess
開啟 CDN
- 到剛建立好的 Bucket 的域名管理中綁定使用者域名,比如
img.example.com
avatar.example.com
- 勾選
,如果域名 dns 解析在阿裡雲,可以勾選阿裡雲 CDN 加速
,如果不在請自行添加域名的自動添加 CNAME 記錄
為cname
阿裡雲 CDN 加速域名
-
CDN 緩存自動重新整理
- 建議單獨為 CDN 申請單獨的根域名,這樣 CDN 請求不會帶上網站的 cookie 等資訊
- CDN 域名管理中對新建立的域名進行配置
- 開啟
私有Bucket回源
-
添加規則,内容目錄緩存過期時間
過期時間為3年,權重99/
-
添加規則,Cache-Control 設定為設定HTTP頭
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
連接配接後填寫到:
,每行一個,并設定檔案權限為 640/etc/passwd-ossfs
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 位址
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicWZwpmLyEmZ5YTOyMjMhFzM1IzYyUmZilDZzUWOzYWZhV2M4I2YlJzYhR2M18CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.jpeg)
- 到論壇背景 -> 站長 -> UCenter 設定 中修改頭像調用方式為
使用靜态位址調用頭像
- 由于有使用者沒有上傳頭像而使用預設頭像,到
bucket 的根目錄添加3個預設頭像檔案 noavatar_big.gif、noavatar_middle.gif 和 noavatar_small.gifavatar
- 修改
中頭像位址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,端口 80源站位址IP
- 其他緩存和 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
并填寫 CDN 位址自定義 URL
http://static.example.com/data/cache/
- 到論壇背景 -> 全局 -> 性能優化 -> 伺服器優化 中修改
小雲 APP 縮略圖接入 CDN
- 如果論壇使用小雲 APP 開發了用戶端程式,且開啟了
功能,同樣可以參照上面附件、頭像的方式接入 OSS 和 CDN生成縮略圖
- 建立
bucket 并開啟 CDN 加速域名thumb
thumb.example.com
- 用 ossfs 将
目錄挂載到/data/htdocs/www/data/appbyme/thumb
bucket,并将已有縮略圖拷貝進去thumb
- 複制一份
/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;但是這些方案都沒有本文的方案更具有通用性和易用性