Apache 簡單頁面緩存

維護一套網站系統,由於時間久遠,已不知道他的靜態化系統要如何開啓和如何運做,而首頁及部分頻道頁由於查詢太多,致使運行緩慢,急需一種簡單有效的方法來提升訪問效率。php

由於問題主要出在頁面中內容的查詢上,優化方法天然是要減小或杜絕查詢,在不動網站系統代碼的前提下,可經過 Apache 的 URLRewrite 來達到目的。數據庫

創建一個目錄(如 cache)來存放靜態化後頁面文件,在網站根目錄的 .htaccess 中寫入規則, 沒有就建立一個:apache

RewriteCond %{DOCUMENT_ROOT}/cache/%{REQUEST_URI}.cache -f
RewriteRule ^(.*)$ cache/$1.cache [L]

此規則判斷 cache 目錄下是否存在當前 URI 對應的 .cache 後綴的文件, 若是有則將請求定向到該文件. 可是網站頁面自己已採用了 URLRewrite 將 url 映射到了程序腳本上, 而其路徑規則可能對尾部的 "/" 不敏感, 如 /abc/def 與 /abc/def/ 能夠是同一個頁面, RewriteCond 並不支持字符串截取、正則替換等操做, 故另添加如下規則來匹配 "/" 結尾的緩存:緩存

RewriteCond %{DOCUMENT_ROOT}/cache/%{REQUEST_URI}/.cache -f
RewriteRule ^(.*)$ cache/$1/.cache [L]

如今, 咱們還須要一個簡單腳原本將頁面輸出存入緩存文件中, 可編寫一個 bash 腳原本實現:bash

#!/bin/bash

WD=$(cd `dirname $0`; pwd)

cache ()
{
    ln="$1"
    fn="$WD/$1.cache"
    tn="$WD/$1.cachx"
    dn=`dirname $fn`

    rm    -f "$fn"
    rm    -f "$tn"
    mkdir -p "$dn"
    wget  -O "$tn" "http://www.xxx.com/$ln"
    mv "$tn" "$fn"
}

if [ "@" != "$1" ]
then
    cache   "$1"
else
    cache ""
    cache xxx/
    cache xxx/xxx
fi

可見腳本中 wget 將輸出存入了臨時文件後改名爲目標文件, 這是由於 wget 在執行開始時就會打開文件, 此時請求開始, apache 因文件存在而重定向, 最後拿到的文件就成空的了. 爲減小網絡請求時間, 可在 /etc/hosts 中加入 127.0.0.1 www.xxx.com網絡

此腳本使用方法爲:優化

./cache.sh          # 緩存首頁
./cache.sh xxx/     # 緩存 xxx 頻道頁(網站內連接可能用 / 結尾)
./cache.sh xxx/xxx  # 緩存 xxx 文章頁(網站內連接不會用 / 結尾)
./cache.sh @        # 緩存全部常常訪問的頁面(腳本 else 部分)

能夠把常常訪問的頁面加入腳本 else 部分, 將此腳本設爲計劃任務, 每隔一段時間刷新緩存一次, 能有效減小請求對數據庫的查詢次數.網站

但這還不夠, 編輯可能須要在發佈文章後當即更新緩存, 以便查看首頁、頻道頁等位置的新聞、推薦等是否正確. 可採用如下 PHP 腳原本執行(若是網站系統是 PHP 編寫):url

<?php

$URIS = array(
    '',
    'xxx/',
    'xxx/xxx',
);

if (isset($_GET['n'])) {
    if (!in_array($_GET['n'], $URIS)) {
        exit('Wrong request');
    }
    $uri = $_GET['n'];
} else {
    $uri = '@';
}

echo  "<pre>\r\n";
system(__DIR__.'/cache.sh \''.$uri.'\' 2>&1');
echo "</pre>\r\n";

只需在須要刷新緩存時請求 /cache/cache.php 便可, 可經過 n 參數來指定僅刷新哪一個頁面. 爲防止惡意利用此腳本執行危險命令(如: abc'; rm -rf 'xxx), 以上判斷了僅能刷新指定的頁面; 固然文件更名或加上密碼等措施可能更可靠些.code

相關文章
相關標籤/搜索