Apache HTTP 伺服器 2.4 版
這份文件補充了 mod_rewrite
參考文件。它提供了一些 mod_rewrite 的進階技術。
分散伺服器負載或儲存空間負擔的一種常見技術稱為「分片」。使用此方法時,前端伺服器會使用 url,將使用者或物件分配到後端伺服器上,以達成「分片」的效果。
使用者對應目標伺服器的對應表,會記錄在外接對應檔案中。它們看起來像這樣
user1 user1 的實體主機
user2 user2 的實體主機
# ... 等等
我們可以將它放入一個 map.users-to-hosts
檔案中。目的是對應;
/u/user1/anypath
到
http://user1 的實體主機/u/user/anypath
因此,每個 URL 路徑不一定要在每個後端實體主機上都是有效的。在對應檔案的協助下,以下的規則集就能發揮這個作用,假設 server0 是預設的伺服器,它會在使用者在對應表中沒有資料時使用
RewriteEngine on RewriteMap users-to-hosts "txt:/path/to/map.users-to-hosts" RewriteRule "^/u/([^/]+)/?(.*)" "http://${users-to-hosts:$1|server0}/u/$1/$2"
有關這個指令語法的詳細說明,請參閱 RewriteMap
文件和 RewriteMap 操作教學。
我們希望動態產生內容,但在產生後一次儲存為靜態內容。這個規則會檢查靜態檔案的存在,如果不存在,會產生靜態檔案。如有需要,可以定期移除靜態檔案(如透過 cron),並會依需要重新產生。
# This example is valid in per-directory context only RewriteCond "%{REQUEST_URI}" "!-U" RewriteRule "^(.+)\.html$" "/regenerate_page.cgi" [PT,L]
-U
運算子會判斷測試字串(本例中為 `REQUEST_URI`)是不是有效的網址。透過次請求完成這動作。如果次請求失敗,也就是所要求的資源不存在,這個規則會呼叫 CGI 程式碼 `regenerate_page.cgi`,產生要求的資源並將其儲存於文件目錄,以便下次要求時可以提供靜態副本。
這樣一來可以以靜態形式提供不常更新的文件。如果需要更新文件,可以從文件目錄中刪除,然後在下次要求時會重新產生。
我們希望使用 mod_rewrite 隨機將負載分配到多個伺服器。
我們會使用 RewriteMap
和一份伺服器清單完成這動作。
RewriteEngine on RewriteMap lb "rnd:/path/to/serverlist.txt" RewriteRule "^/(.*)" "http://${lb:servers}/$1" [P,L]
serverlist.txt
會包含伺服器清單
## serverlist.txt
servers one.example.com|two.example.com|three.example.com
如果您希望其中一個特定的伺服器取得多於其他伺服器的負載,請將其加入更多次至清單中。
Apache 內建一個負載平衡模組 - mod_proxy_balancer
,它的彈性以及功能比您用 mod_rewrite 拼湊起來的要好太多了。
某些擁有數千名使用者的網站會使用結構化的主目錄佈局,也就是每個主目錄都位於一個子目錄中,其開頭(例如)是使用者名稱的第一個字元。因此,/~larry/anypath
是 /home/l/larry/public_html/anypath
,而 /~waldo/anypath
是 /home/w/waldo/public_html/anypath
。
我們使用下列規則集將主目錄 URL 擴充到以上的佈局。
RewriteEngine on RewriteRule "^/~(([a-z])[a-z0-9]+)(.*)" "/home/$2/$1/public_html$3"
預設情形下,重新導向到 HTML 錨點會失敗,因為 mod_rewrite 會將 #
字元轉譯成 %23
,而這會中斷重新導向。
在 RewriteRule
中使用 [NE]
旗標。NE 代表 No Escape(不轉譯)。
我們希望使用 mod_rewrite 依時間提供不同的內容。
有很多 TIME_xxx
變數可用於重寫條件。搭配特殊的字典比對模式 <STRING
、>STRING
和 =STRING
,我們可以執行與時間相關的重新導向
RewriteEngine on RewriteCond "%{TIME_HOUR}%{TIME_MIN}" ">0700" RewriteCond "%{TIME_HOUR}%{TIME_MIN}" "<1900" RewriteRule "^foo\.html$" "foo.day.html" [L] RewriteRule "^foo\.html$" "foo.night.html"
這項措施提供 foo.day.html
的內容在 07:01-18:59
之間於 URL foo.html
中顯示,而其餘時間則顯示 foo.night.html
的內容。
mod_cache
、中間代理伺服器和瀏覽器各會快取回應,並且可能導致任一頁面在已設定的時間區段外顯示。您可以使用 mod_expires
來控制此效果。您當然可以選擇單純以動態方式提供內容,並根據時間客製化內容。有時候,我們希望在執行重新導向時維持某種類型的狀態。例如,您希望註記該重新導向已執行,以便稍後檢查要求是否透過重新導向取得。設定環境變數是一種執行此動作的方法。
使用 [E] 旗標設定環境變數。
RewriteEngine on RewriteRule "^/horse/(.*)" "/pony/$1" [E=rewritten:1]
稍後在規則集中,您可以使用 RewriteCond 檢查這個環境變數。
RewriteCond "%{ENV:rewritten}" "=1"
請注意,環境變數在外部重新導向時無法維持。您可能會考慮使用 [CO] 旗標來設定 cookie。對於每目錄與 htaccess 重新導向(其中最終替換會當作內部重新導向來處理),前一輪重新導向的環境變數會加上 "REDIRECT_" 前綴。