前言
儘管Apache具有重量級、耗資源、低效能(相比其它的WebServer)的特點,但是同時它也具有相容性強、穩定性高、模組豐富等特點,且處理動態請求比大多Web Server要優越。另外,它對Windows的支援要比Nginx與Lighttpd要好。
在選擇Web伺服器時,我們最經常關注的一點是效能(注1),以下附上一個簡單的效能測試結果:
測試伺服器的配置:
Virtualization: OpenVZ RAM: 512MB CPU: 4 cores @ 2.8Ghz OS: CentOS 5
分別安裝了Nginx、Cherokee、Lighttpd和Apache,然後使用並發工具測試,得到如下的結果:
圖片順序為Nginx、Cherokee、Lighttpd、Apache1、Apache2)
650) this.width=650;" style="border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px; border-right-: " title="clip_image004" border="0" alt="clip_image004" align="left" width="138" height="137" src="http://www.bkjia.com/uploads/allimg/131228/12311023C-0.jpg" />650) this.width=650;" style="border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px; border-right-: " title="clip_image006" border="0" alt="clip_image006" align="left" width="140" height="139" src="http://www.bkjia.com/uploads/allimg/131228/1231105939-1.jpg" />650) this.width=650;" style="border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px; border-right-: " title="clip_image008" border="0" alt="clip_image008" align="left" width="141" height="140" src="http://www.bkjia.com/uploads/allimg/131228/1231101a1-2.jpg" />650) this.width=650;" style="border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px; border-right-: " title="clip_image010" border="0" alt="clip_image010" align="left" width="138" height="137" src="http://www.bkjia.com/uploads/allimg/131228/1231106153-3.jpg" />650) this.width=650;" style="border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px; border-right-: " title="clip_image012" border="0" alt="clip_image012" align="left" width="136" height="135" src="http://www.bkjia.com/uploads/allimg/131228/123110IY-4.jpg" /> |
結果顯示Apache的效能並是最好的,但即使如此,由於它對windows的支援以及豐富的模組,還有它於Web領域具有霸主地位。所以我們會經常接觸它,本文就總結自己實際應用到的一些情境。
Apache安裝
http://httpd.apache.org/download.cgi
650) this.width=650;" style="border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px; border-right-: " title="clip_image014" border="0" alt="clip_image014" align="left" width="544" height="256" src="http://www.bkjia.com/uploads/allimg/131228/1231104057-5.jpg" /> |
值得注意的是2.0.64以後的版本,官網中只提供源碼和netware壓縮包,而之前的版本提供msi檔案。由於目標環境為windows,為了簡單起見,本文選擇2.0.64。另,因為安裝都是“next”,所以不再。
Web伺服器
一個典型的配置如下
Alias /url "you/local/path"
<Directory "you/local/path">
Options Indexes FollowSymLinks –ExecCGI
DirectoryIndex index.html home/index.php home/index.html
Order allow,deny
Allow from all
Deny from google.com
</Directory>
說明如下
Alias /url "you/local/path":資源訪問的路徑。
Directory "you/local/path":暴露的本地資源之路徑。
Options Indexes FollowSymLinks –ExecCGI:允許列出目錄的內容;允許目錄的符號鏈;不允許執行CGI指令碼。
DirectoryIndex index.php index.html home/index.php home/index.html:預設首頁
Order allow,deny:後者優先順序大於前者,這一點在後面解釋。
Allow from all:允許來自任何地方的HTTP訪問請求。
Deny from google.com :禁止網域名稱為google.com的HTTP訪問請求。 還記得前面的Order嗎?Deny優先順序優於Allow,故Allow指令雖然聲明允許所有的訪問請求,但是apache仍然禁止來自google.com的請求。
反向 Proxy負載平衡伺服器
反向 Proxy是指,以Proxy 伺服器來接受來自Internet上某個用戶端的串連請求,然後將該請求轉寄至內部網路上的目標伺服器,並將從目標伺服器上得到的結果返回給用戶端的過程。
650) this.width=650;" style="display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto; border-right-: " title="clip_image002" border="0" alt="clip_image002" width="581" height="160" src="http://www.bkjia.com/uploads/allimg/131228/1231106355-6.gif" />
反向 Proxy
反向 Proxy的使用情境主要以下幾個:
1. 加密和SSL加速
2. 負載平衡
3. 緩衝靜態內容
4. 壓縮頁面
5. 減速上傳
6. 安全
7. 外網發布
基於反向 Proxy的負載平衡常用的情境為實現動靜態分離。
使用Apache+Tomcat+快取服務器來實現動靜態分離的方式有三種:JK、http_proxy、ajp_proxy。其中,JK相對後兩者來說配置相對複雜,但是效能較好。JK方式是我們常用的方式。
下面的就是JK一個典型的例子。
JK方式需要額外下載mod_jk模組,地址為
http://www.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/windows/。下載完成後將其中的mod_jk.so檔案拷貝至%APACHE_HOME%/modules目錄下。
JK的配置最關鍵的有三個檔案:
檔案名稱 |
說明 |
http.conf |
前面提到的,Apache伺服器的設定檔,這裡用來載入JK模組以及JK設定檔資訊。 |
workers.properties |
到Tomcat伺服器的連結定義檔案。 |
uriworkermap.properties |
URI對應檔,用來指定哪些URI由Tomcat處理,也可以直接在httpd.conf中配置,但是將這些設定檔單獨放置有一個好處就是JK模組會定期更新該檔案的內容,使得我們修改配置的時候無需重啟Apache伺服器。 |
下面是一個典型的httpd.conf對JK的配置
# (httpd.conf) # 載入 mod_jk 模組 LoadModule jk_module modules/mod_jk.so JkWorkersFile conf/workers.properties JkMountFile conf/uriworkermap.properties JkLogFile logs/mod_jk.log JkLogLevel warn |
接下來需要在conf目錄建立兩個檔案分別是workers.properties、uriworkermap.properties。
內容大概如下
# # workers.properties # # list the workers by name worker.list=DLOG4J, status # localhost server 1 # ------------------------ worker.s1.port=8009 worker.s1.host=localhost worker.s1.type=ajp13 # localhost server 2 # ------------------------ worker.s2.port=8109 worker.s2.host=localhost worker.s2.type=ajp13 worker.s2.stopped=1 worker.DLOG4J.type=lb worker.retries=3 worker.DLOG4J.balanced_workers=s1 worker.DLOG4J.sticky_session=1 worker.status.type=status |
這裡我們配置了兩個類型為 ajp13 的 worker 分別是 s1 和 s2,它們指向同一台伺服器上運行在兩個不同連接埠 8009 和 8109 的 Tomcat。接著我們配置了一個類型為 lb也就是負載平衡的意思)的 worker,它的名字是 DLOG4J。需要說明的是lb是邏輯的 worker,職責是管理前面配置的兩個物理串連 s1 和 s2。最後我們還配置了一個類型為 status 的 worker,用來監控 JK 本身。但是有了這三個 worker 還不夠,我們還需要告訴 JK,哪些 worker 是可用的,所以就有 worker.list = DLOG4J, status 這行配置。
/*=DLOG4J /jkstatus=status !/*.gif=DLOG4J !/*.jpg=DLOG4J !/*.png=DLOG4J !/*.css=DLOG4J !/*.js=DLOG4J !/*.htm=DLOG4J !/*.html=DLOG4J |
配置說明所有的請求都由 DLOG4J 這個 worker 進行處理,除了下面的幾個例外。/jkstatus 請求由 status 這個 worker 處理。另外驚嘆號開頭且符合規則的URI 不要由 JK 進行,包含圖片、css 檔案、js 檔案以及靜態 html 文字檔。
快取服務器
這裡只考慮Apache內建的cache模組,關於與Squid或者varnish等整合另外介紹。
httpd.conf配置如下:
LoadModule cache_module modules/mod_cache.so LoadModule disk_cache_module modules/mod_disk_cache.so UseCanonicalName On <IfModule mod_cache.c> CacheDefaultExpire 3600 CacheMaxExpire 86400 <IfModule mod_disk_cache.c> CacheEnable disk / CacheRoot d:/cache CacheDirLevels 2 CacheDirLength 1 CacheMaxFileSize 1048576 CacheMinFileSize 10 </IfModule> </IfModule> |
配置說明
UseCanonicalName:指令設定為 On 可以使用disk緩衝時顯著提高緩衝的命中率。
CacheDefaultExpire:設定那些既沒有包含"Expires" 或"Cache-Control"頭,也沒有包含"Last-Modified"頭的緩衝對象的預設有效期間(按秒計),預設是為86400秒。
CacheMaxExpire: 指定失效周期的最大值;預設值是一天 (86400)。
CacheEnable disk / 使用disk 緩衝類型 ,這裡為緩衝目錄
CacheRoot d:/cache 存放快取檔案的目錄,需保證啟動並執行使用者擁有該目錄的寫入許可權。
CacheDirLevels指定了子目錄的層數,
CacheDirLength指定了每級子目錄名的字元數
CacheMaxFileSize 快取檔案的最大值byte)
CacheMaxFileSize:快取檔案的最小值byte)。
Log Service
(注2)一個典型的例子:
[Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1] client denied by server configuration: /export/home/live/ap/htdocs/test
第一項是事件發生的日期和時間;第二項是事件的嚴重性, LogLevel指令使只有高於指定嚴重性層級的事件才會被記錄;第三項是產生事件的IP地址;此後是事件本身,在此例中,伺服器拒絕了這個客戶的訪問。伺服器在記錄被訪問檔案時,用的是檔案系統路徑,而不是Web路徑。
本文僅介紹Log Service使用的模組和常用的日誌格式。
1. 訪問日誌
相關模組 |
相關指令 |
· mod_log_config · mod_setenvif |
· CustomLog · LogFormat · SetEnvIf |
訪問日誌中會記錄伺服器所處理的所有請求,其檔案名稱和位置取決於 CustomLog 指令,LogFormat指令可以簡化日誌的內容。這裡闡述訪問日誌的伺服器配置。
不同版本的Apache httpd用了不同的模組和指令來控制對訪問的記錄,包括mod_log_referer, mod_log_agent, 模組和 TransferLog 指令。現在,CustomLog 指令包含了舊版本中相關指令的所有功能。
2. 日誌格式
這是一個典型的記錄格式
LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog logs/access_log common
上述定義了一種特定的日誌格式字串,並給它起了個 別名 叫 common,其中的"%"指示伺服器用某種資訊替換,其他字元資訊則不作替換。引號(")必須加轉義符反斜線,以避免被解釋為字串的結束。格式字串還可以包含特殊控制符,如換行"\n"、定位字元"\t"。
CustomLog指令建立新的使用指定日誌格式的記錄檔,除非其檔案名稱以斜杠開頭,否則其路徑是一個相對於ServerRoot的相對路徑。
上述配置是一個普通的日誌格式,被稱為Common Log Format (CLF),它被許多不同的Web伺服器所採用,並可以為許多日誌剖析器所辯識,它產生的事件記錄有如:
127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326
記錄的各部分說明如下。
127.0.0.1
(%h
)
這是發送請求到伺服器的客戶的IP地址。如果 HostnameLookups 設為 On
,則伺服器會嘗試解析這個IP地址的主機名稱,但是,並不推薦這樣配置,因為會顯著拖慢伺服器,最好是用一個日誌後續處理器還判斷主機名稱,比如 logresolve。如果客戶和伺服器之間存在代理,那麼記錄中的這個IP地址就是那個代理,而不是客戶面前的那個機器的IP地址。
-
(%l
)
這是由用戶端 identd
判斷的RFC 1413身份,輸出中的符號 "-" 表示此處資訊無效。除非在嚴格控制的內部網路中,此資訊通常並不可靠,不應該被使用。只有在IdentityCheck 設為 On
時,Apache才會試圖得到這項資訊。
frank
(%u
)
這是由HTTP認證系統得到的訪問該網頁的客戶名稱,環境變數 REMOTE_USER
會被設為該值並提供給CGI指令碼。如果狀態代碼是401,表示客戶沒有通過認證,則此值沒有意義。如果網頁沒有設定密碼保護,則此項應該是"-
"。
[10/Oct/2000:13:55:36 -0700]
(%t
)
這是伺服器完成對請求的處理時的時間,其格式是:
[day/month/year:hour:minute:second zone]
day = 2*digit
month = 3*letter
year = 4*digit
hour = 2*digit
minute = 2*digit
second = 2*digit
zone = (`+' | `-') 4*digit
可以在格式字串中使用 %{format}t
改變時間的輸出形式,format
與C標準庫中的 strftime(3)
用法相同。
"GET /apache_pb.gif HTTP/1.0"
(\"%r\"
)
引號中是客戶發出的包含了許多有用資訊的請求內容。可以看出,該客戶的動作是GET
,請求的資源是/apache_pb.gif
,使用的協議是HTTP/1.0
。另外,還可以記錄其他資訊,如:格式字串 "%m %U%q %H
" 會記錄動作、路徑、請求串、協議,結果其輸出會和"%r
" 一樣。
200
(%>s
)
這個是伺服器返回給用戶端的狀態代碼。這個資訊非常有價值,因為它指示了請求的結果,或者是被成功響應了(以2開頭),或者被轉向了(以3開頭),或者出錯了(以4開頭),或者產生了伺服器端錯誤(以5開頭)。完整的狀態代碼列表參見HTTP specification (RFC2616 section 10).
2326
(%b
)
最後這項是返回給用戶端的不包括回應標頭的位元組數。如果沒有資訊返回,則此項應該是 "-
",如果希望記錄為 "0
" 的形式,就應該用%B
。
偽靜態技術
偽靜態是一種將動態網頁面請求偽裝成靜態頁面請求的手段,目的是改善動態網頁面對搜尋引擎不好友好的缺點。同時也可以解決動態網頁面不被瀏覽器緩衝的問題,提高系統效能。
一個典型的配置:
# #httpd.conf 配置rewriter模組 LoadModule rewrite_module modules/mod_rewrite.so # <IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^(.*)/forum-([0-9]+)-([0-9]+)\.html$ $1/forumdisplay.jsp?fid=$2&page=$3 </IfModule> |
RewriteEngine 指令開啟或關閉運行時的重寫引擎。如果設定為off,則此模組在運行時不執行任何重寫操作。使用該指令可以使此模組無效,而無須注釋所有的RewriteRule指令!
RewriteRule指令是重寫引擎的根本。此指令可以多次使用。每個指令定義一個簡單的重寫規則。這些規則的定義順序尤為重要——在運行時,規則是按這個順序逐一生效的。
指令後面的參數均為Regex,以下是Regex的常見的用法:
文本 . 任意一個單字元 [chars] 字元類: "chars"中的任意一個字元 [^chars] 字元類: 不在"chars"中的字元 text1|text2 選擇: text1 或 text2 [num1 – num2] 數字類:從num1~num2 量詞 ? 前面的字元出現 0 或 1 次 * 前面的字元出現 0 或 N 次(N > 0) + 前面的字元出現 1 或 N 次(N > 1) 分組 (text) text 組 (常用於設定一個選擇的邊界,或用於產生後引用: 在RewriteRule中可以用 $N 引用第N個分組) 錨 ^ 以之開頭 $ 以之結尾 轉義 \c 對給定的字元c進行轉義 (比如對".[]()"進行轉義,等等) |
當請求URL符合“^(.*)/forum-([0-9]+)-([0-9]+)\.html$”Regex時,RewriteRule將使用後者“$1/forumdisplay.jsp?fid=$2&page=$3”(同樣是Regex)代替前者。代替的順序為 “.*”=>“$1”、“ [0-9]”=>“ $2”、“ [0-9]”=>“ $3”。比如/hh/forum-1-2.html的URL將被替換為/hh/forumdisplay.jsp?fid=1&page=2。
更加詳細的配置請參考注3
AB測試載入器
ab全稱apache benchmark,為apache server內建的效能測試工具,具有輕量、強大等特點。
650) this.width=650;" style="border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px; border-right-: " title="clip_image016" border="0" alt="clip_image016" align="left" width="491" height="552" src="http://www.bkjia.com/uploads/allimg/131228/123110I24-7.jpg" />
結果說明
ServerSoftware: Apache/2.0.64
//待測試伺服器使用之軟體版本
Server Hostname: 127.0.0.1
//伺服器名稱
Server Port: 80
//伺服器連接埠
Document Path: /apache_pb.gif
//訪問路徑
Document Length: 2326 bytes
//頁面大小
Concurrency Level: 10
//(ab測試的)使用的並發數
Time taken for tests: 0.374986 seconds
//總花費時間
Complete requests: 100
//完成的總請求數量
Failed requests: 0
//失敗的請求數量
Write errors: 0
//寫入失敗的次數
Total transferred: 257400 bytes
//總的資料轉送量
HTML transferred: 232600 bytes
//總的HTML內容傳輸量
Requests per second: 266.68 [#/sec] (mean)
//最重要的指標之一,平均每次請求花費的時間
Time per request: 37.499 [ms] (mean)
//最重要的指標之二,平均每秒處理多少個請求
Time per request: 3.750 [ms] (mean, across all concurrent requests)
//與以上的結果差別在於:這個結果是先算每次並發的平均時間t1,
最後再對這些時間求平均值t=(t1…tn)/n。
Transfer rate: 669.36 [Kbytes/sec] received
//平均每秒傳輸的流量,可以協助排除是否存在網路流量過大導致回應時間延長的問題
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 15 35 15.9 31 93
Waiting: 15 35 15.9 31 93
Total: 15 35 15.9 31 93
Percentage of the requests served within a certain time (ms)
50% 31
66% 31
75% 46
80% 46
90% 62
95% 78
98% 78
99% 93
100% 93 (longest request)
//所有請求的響應情況,重點關注90%使用者的回應時間。
常用參數說明
-n 所有請求數
-c 單次產生的請求數,執行次數等於n/c
-t 限制所有請求在制定時間內完成。預設沒有時間限制。
-p 表單提交之資料
-T 表單提交使用之Content-type頭資訊。
-v 設定顯示資訊的等級: - 4或以上顯示頭資訊, 3或以上顯示響應代碼(404, 200等), 2或以上顯示警告和其他資訊。
-V 顯示版本號碼並退出。
-w 以HTML格式輸出結果。
-i 執行HEAD請求,與GET請求不同的是,HEAD請求並不會下載頁面至本地。
注釋
注1 測試結果引自文章http://www.whisperdale.net/11-nginx-vs-cherokee-vs-apache-vs-lighttpd.html
注2 Apache日誌模組官網文檔:http://man.chinaunix.net/newsoft/ApacheManual/logs.html
注3 Apache mod_rewriter模組官方文檔:
http://www.phpchina.com/resource/manual/apache/mod/mod_rewrite.html
本文出自 “jeremy的技術部落格” 部落格,請務必保留此出處http://ijeremy.blog.51cto.com/6126672/1050047