作者: 車東 Email: chedongATbigfoot.com/chedongATchedong.com

寫于:2003/03 最后更新:

版權聲明:可以任意轉載,轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本聲明
http://www.chedong.com/tech/cms.html

關鍵詞:"content manage system" cms path_info cgi php cache squid 內容管理 mod_rewrite url rewrite 系統 緩存 Cacheable "Search engine friendly"

內容摘要:
你完全不必耐心的看到最后,本文主要說明的是在設計CMS時以下2點注意事項:

  1. 搜索引擎友好(Search engine Friendly):基于PATH_INFO的參數解析使得動態網頁在鏈接(URI)形式上更像靜態的目錄結構,大大方便網站內容被搜索引擎收錄;
  2. 可緩存性(Cache Friendly):CMS本身不要過多考慮“效率”問題,只要頁面輸出設計的比較Cacheable,效率問題可以通過更前端專業的緩存服務器解決。

后面附有一個簡單的利用PATH_INFO機制 + SquidWEB加速模式實現PHP動態網頁的靜態發布的例子,比起那些能導出靜態頁面的大型發布系統這種輕量級的動態緩存解決方案只需對原有的動態發布系統做少量的修改,從而大大提高了原有內容發布系統的重用度。

網站內容靜態發布的重要性:Cacheable / Search Engine Friendly

由于一個動態頁面的速度往往會比靜態頁面慢2-10倍,因此對于一個訪問量逐步向百萬級發展的網站來說,訪問速度很快成為一個瓶頸。除了優化內容發布系統的應用本身外,如果能把更新頻率比較低的動態頁面轉存成靜態網頁來發布,速度上的提升效果將是顯著的,而靜態網頁如果能被緩存在內存里,訪問速度更會比原有動態網頁有2-3個數量級的提高。

在國外內容管理系統(CMS)已經是一個非常成熟的行業,能夠真正支撐大訪問的系統中靜態頁面輸出和緩存系統幾乎是必須的。
<a >www.best-code.com</a>
此外隨著互聯網上的內容以驚人速度的增長也越來越突出了搜索引擎的重要性,如果網站想更好地被搜索引擎收錄,網站設計除了面向用戶友好(User Friendly)外,面向搜索引擎友好的設計也是非常重要的。鏈接地址相對固定的靜態網頁比較適合搜索引擎索引,動態網頁后面跟的參數靈活度很大,因此很多搜索引擎都往往會忽略動態頁面,比如:對于news.php?day=22&month=03&year=2003,很多搜索引擎可能只索引news.php這個頁面一次,更多其他參數的頁面可能都會當成相似內容濾掉;我個人一直懷疑在搜索引擎中:即使是同樣內容,靜態頁面往往也比動態網頁的PageRank高。

因此,將動態頁面轉換成靜態頁面,無論從效率上還是面向搜索引擎友好上,都是一個門戶級內容發布系統必須面對的問題。

靜態緩存和動態緩存的比較

靜態頁面的緩存可能有2種形式:

  1. 靜態緩存:是在新內容發布的同時就立刻生成相應內容的靜態頁面,比如:2003年3月22日,管理員通過后臺內容管理界面錄入一篇新聞后,就立刻生成http://www.chedong.com/tech/2003/03/22/001.html這個靜態頁面,并同步更新http://www.chedong.com/tech/index.html這個靜態頁面上的相關鏈接。
  2. 動態緩存:是在新內容發布以后,并不預先生成相應的靜態頁面,直到對相應內容發出請求時,如果前臺緩存服務器找不到相應緩存,就向后臺內容管理服務器發出請求,后臺系統會生成相應內容的靜態頁面,用戶第一次訪問頁面時可能會慢一點,但是以后就是直接訪問緩存了。
    如果去ZDNet等國外網站會發現他們使用的基于Vignette內容管理系統都有這樣的頁面名稱:0,22342566,300458.html。其實這里的0,22342566,300458就是用逗號分割開的多個參數:
    第一次訪問找不到頁面后,相當于會在服務器端產生一個doc_type=0&doc_id=22342566&doc_template=300458的查詢,
    而查詢結果會生成的緩存的靜態頁面:0,22342566,300458.html

靜態緩存的缺點:

  • 復雜的觸發更新機制:這兩種機制在內容管理系統比較簡單的時候都是非常適用的。但對于一個關系比較復雜的網站來說,頁面之間的邏輯引用關系就成為一個非常非常復雜的問題。最典型的例子就是一條新聞要同時出現在新聞首頁和相關的3個新聞專題中,在靜態緩存模式中,每發一篇新文章,除了這篇新聞內容本身的頁面外,還需要系統通過觸發器生成多個新的相關靜態頁面,這些相關邏輯的觸發也往往就會成為內容管理系統中最復雜的部分之一。
  • 舊內容的批量更新: 通過靜態緩存發布的內容,對于以前生成的靜態頁面的內容很難修改,這樣用戶訪問舊頁面時,新的模板根本無法生效。

在動態緩存模式中,內容管理系統只需要關心各個頁面自身,而相關的其他頁面鏈接能自動更新,從而大大減少了設計觸發器設計的需要。

VIGNETTE的動態緩存雖然很好,但是一個系統如果設計得太全面其實也是有很大危險的:如果一個頻道下文章很多:比如達到十萬時,如果生成的靜態頁面都在一個目錄下,對系統文件系統是一個極大的危害,因為一個目錄下文件個數超過3000效率就會非常差,甚至連rm *時都會出現too many arguments錯誤。

簡單的說,一個好的內容管理系統應該包括:
  1. 輸入:方便的內容錄入,所見即所得的編輯界面,權限控制等……
  2. 輸出:方便的模板管理,緩存發布等……
設計或尋找這樣一個系統如果考慮功能全面和高集成度,你會發現只有那些幾十萬$以上的專業內容發布系統才能你滿足所有的需求。

以前做應用的時候也用過一些方式:應用首次訪問以后將生成的內容存成一個緩存文件,下次請求時從緩存目錄中讀取緩存文件,內容更新時,應用把內容從緩存目錄中刪掉,從而減少對數據庫的訪問。雖然這樣做也能承載比較大的負載,但這樣的內容管理和緩存一體的系統是很難分離的。

如果換一個思路:通過一定的分工現內容管理和緩存機制2者的分離,你會發現無論哪一方面可選的余地都是非常大的。甚至有可能利用目前的已經是“功能”比較全面的內容管理系統,而讓所有“效率”問題都由前臺更專業,而且是很容易分布的緩存服務器解決:可以是通過開放源代碼的SQUID做反相代理的WEB加速,可以是專門的緩存硬件設備,甚至是專業的緩存服務商。

動態緩存必須有一個基于靜態鏈接本身的參數解析過程,很多專業內容管理系統系統都是將參數解析機制做成了WEB服務器的模塊實現的。

我們可以把以前的HTTP/GET方式的?key=value改為直接用/value1/value2的方式來傳遞,從而實現了動態頁面的靜態URL形式。而緩存只需要在前端加上一層CACHE服務器,比如:Squid。網站動態內容的動態緩存發布就可以實現了。

按照這個機制實現的發布系統很好地體現了應用系統的分工:把復雜地內容管理系統分解成:內容輸入和緩存這2個相對簡單的系統實現。而中間的內容發布通過URL REWRITE或PATH_INFO解決動態頁面的參數傳遞:

  • 后臺:內容管理系統,專心的將內容發布做好,比如:復雜的工作流管理,復雜的模板規則等……
  • 前臺:頁面的緩存管理則可以使用緩存軟件(比如前臺80端口使用SQUID對后臺8080的內容發布管理系統進行緩存),緩存硬件,甚至交給緩存服務商。
______________________             ___________________
|Squid Software cache| |F5 Hardware cache|
---------------------- -------------------
\ /
\ ________________ /
|ASP |JSP |PHP |
PATH_INFO Based Content Manage System
----------------

    把URI地址用作參數傳遞:URL REWRITE和PATH_INFO

    最近看到很多關于面向搜索引擎URL設計優化(URI Pretty)的文章,提到了很多利用一定機制將動態網頁參數變成像靜態網頁的形式:
    比如可以將:http://www.chedong.com/phpMan.php?mode=man&parameter=ls
    變成:http://www.chedong.com/phpMan.php/man/ls

    最簡單的是基于各種WEB服務器中的URL重寫轉向(Rewrite)模塊的URL轉換:這樣幾乎可以不修改程序的實現將news.asp?id=234的映射成news/234.html

    Apache上有一個模塊(非缺省):mod_rewrite:當然URL REWRITE的強大功能還遠遠不止于此。

    當我需要將將news.asp?id=234的映射成news/234.html時:只需設置:
    RewriteRule /news/(\d+)\.html /news\.asp\?id=$1 [N,I]
    這樣就把 /news/234.html 映射成了 /news.asp?id=234
    當有對/news/234.html的請求時:web服務器會把實際請求轉發給/news.asp?id=234

    而在IIS也有相應的REWRITE模塊:比如ISAPI REWRITEIIS REWRITE,語法都是基于正則表達式,因此語法是幾乎相同的:

    比對于某一個簡單應用可以是:
    RewriteRule /news/(\d+)? /news\.asp\?id=$1 [N,I]
    這樣就把 /news/234 映射到了 /news.asp?id=234

    如我需要把 http://www.myhost.com/foo.php?a=A&b=B&c=C 表現成 http://www.myhost.com/foo.php/a/A/b/B/c/C。而一個更通用的能夠將所有的動態頁面進行參數映射的表達式是:
    RewriteRule (.*?\.php)(\?[^/]*)?/([^/]*)/([^/]*)(.+?)? $1(?2$2&:\?)$3=$4?5$5: [N,I]

    通過URL REWRITE還有一個好處就是隱藏后臺實現:
    比如我們需要將應用從news.asp?id=234遷移成news.php?query=234時,前臺的表現可以一直保持為news/234.html。從實現應用和前臺表現的分離:保持了URL的穩定性,在實現后臺應用平臺的遷移時非常有用。使用mod_rewrite甚至可以把請求轉發到其他后臺服務器上:


    另外一個方式就是基于PATH_INFO:
    PATH_INFO是一個CGI 1.1的標準,所有直接跟在CGI或動態頁面app.cgi后面的"/value_1/value_2"就是PATH_INFO參數:
    比如http://www.chedong.com/phpMan.php/man/ls,中:$PATH_INFO = "/man/ls"

    PATH_INFO是CGI標準,因此PHP Servlet等都有比較好的支持。比如Servlet中就有request.getPathInfo()方法。
    注意:/myapp/servlet/Hello/foo的getPathInfo()返回的是/foo,而/myapp/dir/hello.jsp/foo的getPathInfo()將返回的/hello.jsp,從這里你也可以知道jsp其實就是一個Servlet的PATH_INFO參數。ASP不支持PATH_INFO,

    PHP中基于PATH_INFO的參數解析的例子如下:
    //注意:第一個參數是空的,參數按"/"分割
    if ( isset($_SERVER["PATH_INFO"]) ) {
    ? ? list($nothing, $day, $id) = explode('/', $_SERVER["PATH_INFO"]);
    }

    如何隱蔽應用:例如.php,的擴展名:
    在APACHE中這樣配置:
    <FilesMatch "^app_name$">
    ? ? ForceType application/x-httpd-php
    </FilesMatch>

    如何更像靜態頁面:app_name/my/app.html
    解析的PATH_INFO參數的時候,把最后一個參數的最后5個字符“.html”截斷即可。
    注意:APACHE2中缺省是不允許PATH_INFO的,需要設置
    AcceptPathInfo on

    特別是針對使用虛擬主機用戶,無權安裝和配置mod_rewrite的時候,PATH_INFO往往就成了唯一的選擇。

    雖然通過修改設置SQUID也可以對帶?的動態頁面進行緩存,但為了方便搜索引擎收錄索引,還是將參數改成PATH_INFO比較好。

    OK,這樣以后看見類似于http://www.example.com/article/234這樣的網頁你就知道其實是article/show.php?id=234這個php程序生成的動態網頁,很多站點表面看上去可能有很多靜態目錄,其實很有可能都是使用1,2個程序實現的內容發布。比如很多WIKIWIKI系統都使用了這個機制:整個系統就一個簡單的wiki程序,而看上去的目錄其實都是這個應用拿后面的地址作為參數的查詢結果。

    利用基于MOD_REWRITE/PATH_INFO + CACHE服務器的解決方案對原有的動態發布系統進行改造,也可以大大降低舊有系統升級到新的內容管理系統的成本。

    面向緩存的頁面設計

    讓頁面能夠比較好的被緩存服務器緩存,必須在產生內容的WEB服務器上設置,讓返回內容的HTTP HEADER中加入"Last-Modified"和"Expires"聲明,比如:
    Last-Modified: Wed, 14 May 2003 13:06:17 GMT
    Expires: Fri, 13 Jun 2003 13:06:17 GMT
    以允許前端SQUID服務器緩存:
    • 頁面必須包含Last-Modified: 標記,一般純靜態頁面本身都會有Last-Modified信息,動態頁面需要通過函數強制加上,比如PHP中:
      ??? // always modified now
      ??? header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");

    • 必須有Expires或Cache-Control: max-age標記設置頁面的過期時間:
      對于靜態頁面,通過apache的mod_expires根據頁面的MIME類型設置緩存周期:比如圖片缺省是1個月,HTML頁面缺省是2天等。
      <IfModule mod_expires.c>
      ? ? ExpiresActive on
      ? ? ExpiresByType image/gif "access plus 1 month"
      ? ? ExpiresByType text/css "now plus 2 day"
      ? ? ExpiresDefault "now plus 1 day"
      </IfModule>

      對于動態頁面,則可以直接通過寫入HTTP返回的頭信息,比如對于新聞首頁index.php可以是20分鐘,而對于具體的一條新聞頁面可能是1天后過期。比如:在php中加入了1個月后過期:
      ??? // Expires one month later
      ??? header("Expires: " .gmdate ("D, d M Y H:i:s", time() + 3600 * 24 * 30). " GMT");

    • 如果服務器端有基于HTTP的認證,必須有Cache-Control: public標記
    ASP應用的緩存設計:
    首先在公用的包含文件中(比如include.asp)加入以下公用函數:
    <%
    ' Converts date (19991022 11:08:38) to http form (Fri, 22 Oct 1999 12:08:38 GMT)
    Function DateToHTTPDate(ByVal OleDATE)
    ? Const GMTdiff = #08:00:00#
    ? OleDATE = OleDATE - GMTdiff
    ? DateToHTTPDate = engWeekDayName(OleDATE) & _
    ??? ", " & Right("0" & Day(OleDATE),2) & " " & engMonthName(OleDATE) & _
    ??? " " & Year(OleDATE) & " " & Right("0" & Hour(OleDATE),2) & _
    ??? ":" & Right("0" & Minute(OleDATE),2) & ":" & Right("0" & Second(OleDATE),2) & " GMT"
    End Function

    Function engWeekDayName(dt)
    ??? Dim Out
    ??? Select Case WeekDay(dt,1)
    ??? ??? Case 1:Out="Sun"
    ??? ??? Case 2:Out="Mon"
    ??? ??? Case 3:Out="Tue"
    ??? ??? Case 4:Out="Wed"
    ??? ??? Case 5:Out="Thu"
    ??? ??? Case 6:Out="Fri"
    ??? ??? Case 7:Out="Sat"
    ??? End Select
    ??? engWeekDayName = Out
    End Function

    Function engMonthName(dt)
    ??? Dim Out
    ??? Select Case Month(dt)
    ??? ??? Case 1:Out="Jan"
    ??? ??? Case 2:Out="Feb"
    ??? ??? Case 3:Out="Mar"
    ??? ??? Case 4:Out="Apr"
    ??? ??? Case 5:Out="May"
    ??? ??? Case 6:Out="Jun"
    ??? ??? Case 7:Out="Jul"
    ??? ??? Case 8:Out="Aug"
    ??? ??? Case 9:Out="Sep"
    ??? ??? Case 10:Out="Oct"
    ??? ??? Case 11:Out="Nov"
    ??? ??? Case 12:Out="Dec"
    ??? End Select
    ??? engMonthName = Out
    End Function
    %>

    然后在具體的頁面中,比如index.asp和news.asp的“最上面”加入以下代碼:HTTP Header

    <!--#include file="../include.asp"-->
    <%
    ' set Page Last-Modified Header:
    ' Converts date (19991022 11:08:38) to http form (Fri, 22 Oct 1999 12:08:38 GMT)
    Response.AddHeader "Last-Modified", DateToHTTPDate(Now())

    ' The Page Expires in Minutes
    Response.Expires = 60

    ' Set cache control to externel applications
    Response.CacheControl = "public"
    %>

    其中Response.Expires 是設置頁面過期時間的:單位是分鐘

    如何檢查目前站點頁面的可緩存性(Cacheablility)呢?可以參考以下2個站點上的工具:
    http://www.ircache.net/cgi-bin/cacheability.py

    面向緩存的站點規劃

    一個利用SQUID的Transparent對多個站點進行做WEB加速http acceleration方案:

    原先一個站點的規劃可能是這樣的:
    200.200.200.207 www.chedong.com
    200.200.200.208 news.chedong.com
    200.200.200.209 bbs.chedong.com
    200.200.200.205 images.chedong.com

    在SQUID模式下:所有站點都通過外部DNS指向到同一個IP:200.200.200.200/201這2臺SQUID緩存服務器上(使用2臺是為了冗余備份)
                              _____________________   ________
    www.chedong.com 請求 \ | Squid cache box | | | / 192.168.0.4 www.chedong.com
    news.chedong.com 請求 -| 200.200.200.200/201 |-|firewall| - 192.168.0.4 news.chedong.com
    bbs.chedong.com 請求 / | /etc/hosts | | box | \ 192.168.0.3 bbs.chedong.com
    --------------------- --------
    編譯和配置過程:
    1. ./configure --enable-referer-log --disable-internal-dns
      --disable-internal-dns:禁用SQUID的DNS解析
      --enable-referer-log:便于APACHE COMBINED格式日志生成

    2. 配置:
      http_port 80
      httpd_accel_host virtual
      httpd_accel_port 8000
      httpd_accel_uses_host_header on

      # accelerater my domain only
      acl acceleratedHosts dstdom_regex chedong.com
      # accelerater http protocol on port 80
      acl acceleratedProtocol protocol HTTP
      acl acceleratedPort port 80
      # access arc
      acl all src 0.0.0.0/0.0.0.0

      # Allow requests when they are to the accelerated machine AND to the
      # right port with right protocol
      http_access allow acceleratedProtocol acceleratedPort acceleratedHosts
      http_access allow all
    在/etc/hosts中:加入內部的DNS解析,比如:
    192.168.0.4 www.chedong.com
    192.168.0.4 news.chedong.com
    192.168.0.3 bbs.chedong.com

    工作原理:
    SQUID服務器上關閉了DNS解析,這樣,請求外部過來時,設置SQUID根據/etc/hosts文件進行內部DNS解析。這樣,服務器請求就可以轉發到我們指定的內部地址上。

    使用SQUID的反相代理加速,我們不僅可以得到性能上的提升,而且還能獲得額外的安全性和配置的靈活度:
    • 配置靈活性提高:可以自己在內部服務器上控制后臺服務器的DNS解析,當需要在服務器之間做遷移調整時,就不用大量修改外部DNS配置了,只需要修改內部DNS實現服務的調整。
    • 數據安全性增加:所有后臺服務器可以很方便的被保護在防火墻內。
    • 后臺應用設計復雜程度降低:原先為了效率常常需要建立專門的圖片服務器images.chedong.com和負載比較高的應用服務器bbs.chedong.com分離,在SQUID加速模式中,所有前臺請求都通過SQUID服務器:實際上就都是靜態頁面,這樣,應用設計時就不用考慮圖片和應用本身分離了,也大大降低了后臺內容發布系統設計的復雜程度,由于數據和應用都存放在一起,也方便了文件系統的維護和管理。
    小節:
    • 大訪問量的網站應盡可能將動態網頁生成靜態頁面作為緩存發布,甚至對于搜索引擎這樣的動態應用來說,緩存機制也是非常非常重要的。
    • 利用PATH_INFO機制進行解析參數,實現動態網頁鏈接的美化,方便搜索引擎的索引;
    • 在動態頁面中利用HTTP Header定義緩存更新策略。
    • 利用緩存服務器獲得額外的配置和安全性
    • 日志非常重要:SQUID日志缺省不支持COMBINED日志,但REFERER日志對于站點分析非常重要,在GNU/Linux可以用以下方式生成:
      pr -mJt access.log referer.log | awk '{print $1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9" "$10" \x22"$14"\x22 \x22"$11"\x22"}'? > combined.log
      ??? -m merge
      ??? -J join line
      ??? -t omit header and footer

    附1:SQUID性能測試試驗

    phpMan.php是一個基于php的man page server,每個man page需要調用后臺的man命令和很多頁面格式化工具,系統負載比較高,提供了Cache Friendly的URL,以下是針對同樣的頁面的性能測試資料:
    測試環境:Redhat 8 on Cyrix 266 / 192M Mem
    測試程序:使用apache的ab(apache benchmark):
    測試條件:請求50次,并發50個連接
    測試項目:直接通過apache 1.3 (80端口) vs squid 2.5(8000端口:加速80端口)

    測試1:無CACHE的80端口動態輸出:
    ab -n 100 -c 10 http://www.chedong.com:81/phpMan.php/man/kill/1
    This is ApacheBench, Version 1.3d <$Revision: 1.58 $> apache-1.3
    Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Copyright (c) 1998-2001 The Apache Group, http://www.apache.org/

    Benchmarking localhost (be patient).....done
    Server Software:??????? Apache/1.3.23?????????????????????????????????????
    Server Hostname:??????? localhost
    Server Port:??????????? 80

    Document Path:????????? /phpMan.php/man/kill/1
    Document Length:??????? 4655 bytes

    Concurrency Level:????? 5
    Time taken for tests:?? 63.164 seconds
    Complete requests:????? 50
    Failed requests:??????? 0
    Broken pipe errors:???? 0
    Total transferred:????? 245900 bytes
    HTML transferred:?????? 232750 bytes
    Requests per second:??? 0.79 [#/sec] (mean)
    Time per request:?????? 6316.40 [ms] (mean)
    Time per request:?????? 1263.28 [ms] (mean, across all concurrent requests)
    Transfer rate:????????? 3.89 [Kbytes/sec] received

    Connnection Times (ms)
    ????????????? min? mean[+/-sd] median?? max
    Connect:??????? 0??? 29? 106.1????? 0?? 553
    Processing:? 2942? 6016 1845.4?? 6227 10796
    Waiting:???? 2941? 5999 1850.7?? 6226 10795
    Total:?????? 2942? 6045 1825.9?? 6227 10796

    Percentage of the requests served within a certain time (ms)
    ? 50%?? 6227
    ? 66%?? 7069
    ? 75%?? 7190
    ? 80%?? 7474
    ? 90%?? 8195
    ? 95%?? 8898
    ? 98%?? 9721
    ? 99%? 10796
    ?100%? 10796 (last request)

    測試2:SQUID緩存輸出
    /home/apache/bin/ab -n50 -c5 "http://localhost:8000/phpMan.php/man/kill/1"
    This is ApacheBench, Version 1.3d <$Revision: 1.58 $> apache-1.3
    Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
    Copyright (c) 1998-2001 The Apache Group, http://www.apache.org/

    Benchmarking localhost (be patient).....done
    Server Software:??????? Apache/1.3.23?????????????????????????????????????
    Server Hostname:??????? localhost
    Server Port:??????????? 8000

    Document Path:????????? /phpMan.php/man/kill/1
    Document Length:??????? 4655 bytes

    Concurrency Level:????? 5
    Time taken for tests:?? 4.265 seconds
    Complete requests:????? 50
    Failed requests:??????? 0
    Broken pipe errors:???? 0
    Total transferred:????? 248043 bytes
    HTML transferred:?????? 232750 bytes
    Requests per second:??? 11.72 [#/sec] (mean)
    Time per request:?????? 426.50 [ms] (mean)
    Time per request:?????? 85.30 [ms] (mean, across all concurrent requests)
    Transfer rate:????????? 58.16 [Kbytes/sec] received

    Connnection Times (ms)
    ????????????? min? mean[+/-sd] median?? max
    Connect:??????? 0???? 1??? 9.5????? 0??? 68
    Processing:???? 7??? 83? 537.4????? 7? 3808
    Waiting:??????? 5??? 81? 529.1????? 6? 3748
    Total:????????? 7??? 84? 547.0????? 7? 3876

    Percentage of the requests served within a certain time (ms)
    ? 50%????? 7
    ? 66%????? 7
    ? 75%????? 7
    ? 80%????? 7
    ? 90%????? 7
    ? 95%????? 7
    ? 98%????? 8
    ? 99%?? 3876
    ?100%?? 3876 (last request)

    結論:No Cache / Cache = 6045 / 84 = 70
    結論:對于可能被緩存請求的頁面,服務器速度可以有2個數量級的提高,因為SQUID是把緩存頁面放在內存里的(因此幾乎沒有硬盤I/O操作)。

    附2:一個CACHE多主機APACHE服務的SQUID安裝配置:

    squid的編譯:
    ./configure --enable-useragent-log? --enable-referer-log --enable-default-err-language=Simplify_Chinese --enable-err-languages="Simplify_Chinese English" --disable-internal-dns?
    make
    #make install
    #cd /usr/local/squid
    make dir cache
    chown squid.squid *
    vi /usr/local/squid/etc/squid.conf

    ---------------------cut here----------------------------------
    # visible name
    visible_hostname cache.example.com

    # cache config: space use 1G and memory use 256M
    cache_dir ufs /usr/local/squid/cache 1024 16 256
    cache_mem 256 MB
    cache_effective_user squid
    cache_effective_group squid


    http_port 80
    httpd_accel_host virtual
    httpd_accel_single_host off
    httpd_accel_port 80
    httpd_accel_uses_host_header on
    httpd_accel_with_proxy on

    # accelerater my domain only
    acl acceleratedHostA dstdomain .example1.com
    acl acceleratedHostB dstdomain .example2.com
    acl acceleratedHostC dstdomain .example3.com
    # accelerater http protocol on port 80
    acl acceleratedProtocol protocol HTTP
    acl acceleratedPort port 80
    # access arc
    acl all src 0.0.0.0/0.0.0.0

    # Allow requests when they are to the accelerated machine AND to the
    # right port with right protocol
    http_access allow acceleratedProtocol acceleratedPort acceleratedHostA
    http_access allow acceleratedProtocol acceleratedPort acceleratedHostB
    http_access allow acceleratedProtocol acceleratedPort acceleratedHostC

    # logging
    emulate_httpd_log on
    referer_log /usr/local/squid/var/logs/referer.log
    useragent_log /usr/local/squid/var/logs/agent.log


    ----------------------cut here---------------------------------

    創建緩存目錄:
    /usr/local/squid/sbin/squid -z

    啟動squid
    /usr/local/squid/sbin/squid

    停止squid:
    /usr/local/squid/sbin/squid -k shutdown

    啟用新配置:
    /usr/local/squid/sbin/squid -k reconfig

    通過crontab每天0點截斷/輪循日志:
    0 0 * * * (/usr/local/squid/sbin/squid -k rotate)

    附3:如何在IIS上利用PHP支持PATH_INFO

    PHP的ISAPI模式安裝備忘:只試成 php-4.2.3-Win32

    解包目錄
    ========
    php-4.2.3-Win32.zip c:\php

    PHP.INI初始化文件
    =================
    復制:c:\php\php.ini-dist 到 c:\winnt\php.ini

    配置文件關聯
    ============
    按照install.txt中的說明配置文件關聯

    運行庫文件
    ==========
    復制 c:\php\php4ts.dll 到 c:\winnt\system32\php4ts.dll

    這樣運行后:會發現php把PATH_INFO映射到了物理路徑上
    Warning: Unknown(C:\CheDong\Downloads\ariadne\www\test.php\path): failed to create stream: No such file or directory in Unknown on line 0

    Warning: Unknown(): Failed opening 'C:\CheDong\Downloads\ariadne\www\test.php\path' for inclusion (include_path='.;c:\php4\pear') in Unknown on line 0

    安裝ariadne的PATCH
    ==================
    停止IIS服務
    net stop iisadmin
    ftp://ftp.muze.nl/pub/ariadne/win/iis/php-4.2.3/php4isapi.dll
    覆蓋原有的c:\php\sapi\php4isapi.dll

    注:ariadne是一個基于PATH_INFO的內容發布系統

    PHP 4.3.2 RC2中CGI模式的PATH_INFO已經修正,照常安裝即可。
    www.best-code.com

    參考資料:

    CMS行業觀察
    http://www.cmswatch.com

    CMS討論郵件列表
    http://www.cms-list.org

    一個基于PATH_INFO的開源內容管理系統
    http://typo3.com/

    商業的和開源CMS項目列表:
    http://directory.google.com/Top/Computers/Software/Internet/Site_Management/Content_Management/

    搜索引擎友好的URL設計
    http://www.sitepoint.com/article/485
    說不定這個URL原來就是articel.php?id=485

    HTTP代理緩存
    http://vancouver-webpages.com/proxy.html

    可緩存的頁面設計
    http://linux.oreillynet.com/pub/a/linux/2002/02/28/cachefriendly.html

    相關RFC文檔:

    可緩存性檢查:
    http://www.web-caching.com/cacheability.html

    URL Rewrite文檔:
    http://www.isapirewrite.com/docs/
    http://httpd.apache.org/docs/mod/mod_rewrite.html
    http://httpd.apache.org/docs-2.0/mod/mod_rewrite.html

    原文出處:<a >http://www.chedong.com/tech/cms.html</a>