Monthly Archive八月 2005
網路科技 dada on 八月 01, 2005
動態網頁也可以被快取喔! (Part II)
接續前面那一篇「動態網頁也可以被快取喔!」
前面這樣的修改事實上仍不太夠,在某些狀況下仍無法節省頻寬,甚至有些時候會發生檔案更新後,抓到的檔案還是舊的
這一篇作法嘗試進一步解決這些問題,我們把前面的程式再作一些修改:
<? # http://bbs.giga.net.tw/demo/dl-test3.php $filename = 'Peacock.jpg'; $ims = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE'] ); $mod_time = gmdate('D, d M Y H:i:s', filemtime($filename)) . ' GMT'; if( $mod_time == $ims ) { header( 'HTTP/1.0 304 Not Modified' ); exit; } header( 'Cache-Control: max-age=60' ); header( 'Last-Modified: ' . $mod_time ); header( 'Content-Type: application/octet-stream' ); header( 'Content-Length: ' . filesize($filename) ); header( 'Content-Transfer-Encoding: binary' ); header( 'Content-Disposition: attachment; filename="'.$filename.'"' ); $fp = fopen( $filename, 'rb' ); while( !feof($fp) ) { echo fread( $fp, 1024 ); } fclose($fp); ?>
這邊作一些說明:
WebAMP 對於已經存取過的檔案,會對 Web Server 發出 If-Modified-Since 的請求,要求 Web Server 確認該檔案是否已經修改過了
所以程式首先抓取 $_SERVER['HTTP_IF_MODIFIED_SINCE'] 變數,與 Last-Modified 比較,如果發現兩者相同,就回傳 HTTP/1.0 304 Not Modified 告知 WebAMP 這個檔案沒更新過然後直接結束程式 ( exit ),避免耗費頻寬
另外就是加上 Cache-Control: max-age=60 這個指令:
max-age 的效用等同以前的 Expires: header,但是使用起來更方便一點 (只須指定秒數)
max-age=60 是告知 WebAMP 該檔案 60 秒內都不會更新
這個設定會讓 WebAMP 在 60 秒內都不會來問 Web Server 是否有更新,可以降低 Server 的一些負載,超過 60 秒以後,WebAMP 會用 If-Modified-Since 的方式去問 Web Server 該檔案是否有更新
你可以依據需求以及檔案更新的頻率來適當調整這個數值
修改之後,除了第一次之外,結果當然是讓人滿意的囉:
# wget -v -S 'http://bbs.giga.net.tw/demo/dl-test3.php'
--15:12:36-- http://bbs.giga.net.tw/demo/dl-test3.php
=> `dl-test3.php'
Resolving bbs.giga.net.tw... done.
Connecting to bbs.giga.net.tw[203.187.29.180]:80... connected.
HTTP request sent, awaiting response...
1 HTTP/1.0 200 OK
2 Date: Mon, 01 Aug 2005 07:04:49 GMT
3 Server: Apache/2.0.54 (FreeBSD) PHP/5.0.4
4 X-Powered-By: PHP/5.0.4
5 Cache-Control: max-age=60
6 Last-Modified: Tue, 18 May 2004 08:53:23 GMT
7 Content-Length: 1474750
8 Content-Transfer-Encoding: binary
9 Content-Disposition: attachment; filename="Peacock.jpg"
10 Content-Type: application/octet-stream
11 X-Cache: HIT from WebAmpRP@GIGAMEDIA
12 Connection: close
100%[====================================>] 1,474,750 1.32M/s
最後,我們回過頭來看看 Web Server 端的 LOG (access.log)
第一次下載 dl-test3.php 時,當然是 MISS 的,這時候的狀態碼是 200 :
203.187.29.181 - - [01/Aug/2005:14:51:01 +0800] "GET /demo/dl-test3.php HTTP/1.0"
200 1474750 "http://bbs.giga.net.tw/" "Wget/1.8.2"
由於我們前面設定了 max-age=60,因此在 60 秒之內重複下載 dl-test3.php,都會由 WebAMP 直接處理掉,而不會在 Web Server 上面看到任何 LOG
但超過 60 秒後,你就會在 Web Server 上面看到 304 的狀態碼 (要求確認是否更新過):
203.187.29.181 - - [01/Aug/2005:14:52:06 +0800] "GET /demo/dl-test3.php HTTP/1.0"
304 - "http://bbs.giga.net.tw/" "Wget/1.8.2"
確認過後,一樣要再隔 60 秒才會再向 Web Server 問一次 If-Modified-Since
最後,想瞭解更進一步資訊的,下面幾個連結可以參考看看:
- Caching Tutorial (for Web Authors and Webmasters)
- HTTP 1.1 - Header Field Definitions
歡迎大家都來試用看看 WebAMP 的服務!
以上這些作法不只適用於 WebAMP,只要您想要讓動態網頁可以被 Proxy 快取,都可以使用上述方法來修改程式
網路科技 dada on 八月 01, 2005
動態網頁也可以被快取喔!
很多人都以為 WebAMP 只能給靜態網頁使用,動態網頁無法得到任何加速效果
但其實只要程式設計得宜,動態網頁也有可能可以享受到 WebAMP 的網站超頻加速的效果喔
以下我們用一個簡單的例子來說明:
首先,我們先看這個原始圖片,大小約為 1.4 MBytes:
http://bbs.giga.net.tw/demo/Peacock.jpg
由於這個檔案是靜態檔案,因此理所當然會被 WebAMP 加速 (HIT),我們用 wget 來驗證看看:
# wget -v -S 'http://bbs.giga.net.tw/demo/Peacock.jpg'
--10:07:00-- http://bbs.giga.net.tw/demo/Peacock.jpg
=> `Peacock.jpg'
Resolving bbs.giga.net.tw... done.
Connecting to bbs.giga.net.tw[203.187.29.180]:80... connected.
HTTP request sent, awaiting response...
1 HTTP/1.0 200 OK
2 Date: Sat, 12 Mar 2005 15:25:22 GMT
3 Server: Apache/2.0.52 (FreeBSD) PHP/5.0.3
4 Last-Modified: Tue, 18 May 2004 08:53:23 GMT
5 ETag: "51b65-1680be-12ff86c0"
6 Accept-Ranges: bytes
7 Content-Length: 1474750
8 Content-Type: image/jpeg
9 Age: 259658
10 X-Cache: HIT from WebAmpRP@GIGAMEDIA
11 Connection: close
100%[====================================>] 1,474,750 974.42K/s
接下來,我們測試一下用程式來動態輸出這個圖片,首先我們寫了一支 PHP 程式:
<? # http://bbs.giga.net.tw/demo/dl-test1.php $filename = 'Peacock.jpg'; header( 'Content-Type: application/octet-stream' ); header( 'Content-Length: ' . filesize($filename) ); header( 'Content-Transfer-Encoding: binary' ); header( 'Content-Disposition: attachment; filename="'.$filename.'"' ); $fp = fopen( $filename, 'rb' ); while( !feof($fp) ) { echo fread( $fp, 1024 ); } fclose($fp); ?>
然後,我們用 wget 測試幾次看看:
# wget -v -S 'http://bbs.giga.net.tw/demo/dl-test1.php'
--10:14:29-- http://bbs.giga.net.tw/demo/dl-test1.php
=> `dl-test1.php'
Resolving bbs.giga.net.tw... done.
Connecting to bbs.giga.net.tw[203.187.29.180]:80... connected.
HTTP request sent, awaiting response...
1 HTTP/1.0 200 OK
2 Date: Mon, 01 Aug 2005 02:14:33 GMT
3 Server: Apache/2.0.54 (FreeBSD) PHP/5.0.4
4 X-Powered-By: PHP/5.0.4
5 Content-Length: 1474750
6 Content-Transfer-Encoding: binary
7 Content-Disposition: attachment; filename="Peacock.jpg"
8 Content-Type: application/octet-stream
9 X-Cache: MISS from WebAmpRP@GIGAMEDIA
10 Connection: close
100%[====================================>] 1,474,750 325.21K/s
我們會發覺不管測試幾次,都會是 MISS 的情形!
接下來,我們稍微修改一下程式,加上 Last-Modified: 的 HTTP header ...
<? # http://bbs.giga.net.tw/demo/dl-test2.php $filename = 'Peacock.jpg'; header( 'Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($filename) ) . ' GMT'); header( 'Content-Type: application/octet-stream' ); header( 'Content-Length: ' . filesize($filename) ); header( 'Content-Transfer-Encoding: binary' ); header( 'Content-Disposition: attachment; filename="'.$filename.'"' ); $fp = fopen( $filename, 'rb' ); while( !feof($fp) ) { echo fread( $fp, 1024 ); } fclose($fp); ?>
上面 filemtime($filename) 主要是拿檔案的修改時間來當作 Last-Modified: 時間,不過要用 gmdate() 把 UNIX Timestamp 轉換成 GMT 格林威治時區的時間
加了上面 Last-Modified 這一行之後,我們再來測試一下:
% wget -v -S 'http://bbs.giga.net.tw/demo/dl-test2.php'
--09:56:23-- http://bbs.giga.net.tw/demo/dl-test2.php
=> `dl-test2.php'
Resolving bbs.giga.net.tw... done.
Connecting to bbs.giga.net.tw[203.187.29.180]:80... connected.
HTTP request sent, awaiting response...
1 HTTP/1.0 200 OK
2 Date: Mon, 01 Aug 2005 01:56:25 GMT
3 Server: Apache/2.0.54 (FreeBSD) PHP/5.0.4
4 X-Powered-By: PHP/5.0.4
5 Last-Modified: Tue, 18 May 2004 08:53:23 GMT
6 Content-Length: 1474750
7 Content-Transfer-Encoding: binary
8 Content-Disposition: attachment; filename="Peacock.jpg"
9 Content-Type: application/octet-stream
10 X-Cache: MISS from WebAmpRP@GIGAMEDIA
11 Connection: close
100%[====================================>] 1,474,750 350.20K/s
第一次當然還是 MISS,不過第二次以後就都是 HIT 了
# wget -v -S 'http://bbs.giga.net.tw/demo/dl-test2.php'
--09:56:26-- http://bbs.giga.net.tw/demo/dl-test2.php
=> `dl-test2.php'
Resolving bbs.giga.net.tw... done.
Connecting to bbs.giga.net.tw[203.187.29.180]:80... connected.
HTTP request sent, awaiting response...
1 HTTP/1.0 200 OK
2 Date: Mon, 01 Aug 2005 01:56:25 GMT
3 Server: Apache/2.0.54 (FreeBSD) PHP/5.0.4
4 X-Powered-By: PHP/5.0.4
5 Last-Modified: Tue, 18 May 2004 08:53:23 GMT
6 Content-Length: 1474750
7 Content-Transfer-Encoding: binary
8 Content-Disposition: attachment; filename="Peacock.jpg"
9 Content-Type: application/octet-stream
10 Age: 4
11 X-Cache: HIT from WebAmpRP@GIGAMEDIA
12 Connection: close
100%[====================================>] 1,474,750 950.12K/s
以上是以圖片作例子,你也可以代換成要被下載的檔案 (有些人會用這種方式來計算檔案被下載的次數)
甚至,討論區的文章如果能被正確貼上 Last-Modified: 的 header,也有可能可以享受到 WebAMP 加速的好處喔
更進一步的資訊,請參考下一篇「動態網頁也可以被快取喔! (Part II)」