LAMP系統效能調優 最佳化Apache和PHP

來源:互聯網
上載者:User

如今,使用 LAMP(Linux
、Apache、MySQL
和 PHP
/Perl)架構的應用程式不斷被開發和部署。但是,伺服器管理
員常常對應用程式本身幾乎沒有控制能力,因為應用程式是別人編寫的。這份 共三部分的系列文章 將討論許多伺服器配置問題
,這些配置會影響應用程式的效能。第二篇文章重點討論可為最佳化 Apache 和 PHP 而採取的措施。

Linux、 Apache、MySQL
和 PHP(或 Perl)是許多 Web 應用程式的 LAMP 架構的基礎。有很多基於 LAMP 組件的開源軟體包可用於解決各種各樣的問題。隨著應用程式負載的增加,底層基礎設施的瓶頸也會越來越明顯,其表現形式就是響應使用者請求的速度變慢。 上一篇文章
展示了調優 Linux 系統的方法,還介紹了 LAMP 和效能度量的基礎知識。本文重點關注 Web 服務器組件:Apache 和 PHP。

調優 Apache

Apache 是一種高度可配置的軟體。它具有大量特性,但每一種都代價高昂。從某種程度上來說,調優 Apache 來說就是以恰當的方式分配資源,還涉及到將配置簡化為僅包含必要內容。

配置 MPM

Apache 是模組化的,因為可以輕鬆添加和移除特性。在 Apache 的核心,多處理模組(Multi-Processing
Module,MPM)提供了這種模組化功能性 —— 管理網路連接、調度請求。MPM 使您能夠使用線程,甚至能夠將 Apache 遷移到另外一個作業系統

每次只能有一個 MPM 是活動的,必須使用 --with-mpm=(worker|prefork|event) 靜態編譯。

每個請求使用一個進程的傳統模型稱為 prefork。較新的線程化模型稱為
worker,它使用多個進程,每個進程又有多個線程,這樣就能以較低的開銷獲得更好的效能。最新的 event MPM
是一種實驗性的模型,為不同的任務使用單獨的線程池。要確定當前使用的是哪種 MPM,可執行 httpd -l。

選擇使用何種 MPM 取決於許多因素。在 event MPM
脫離實驗狀態之前,不應考慮這種模型,而是在使用線程和不使用線程之間作出選擇。表面上看來,如果所有底層模組(包括 PHP
使用的所有庫)都是安全執行緒的,線程要優於分叉(forking)。而 Prefork 是較為安全的選擇;如果選擇了
worker,則應該謹慎測試。效能收益還取決於您的發布版所附帶的庫及硬體。

無論選擇了哪種 MPM,都必須恰當地配置它。一般而言,配置 MPM 包括告知 Apache 怎樣去控制有多少 worker 正在運行,它們是線程還是進程。prefork MPM 的重要配置選項如清單 1 所示。

清單 1. prefork MPM 的配置

  1. StartServers      50
  2. MinSpareServers  15
  3. MaxSpareServers  30
  4. MaxClients      225
  5. MaxRequestsPerChild 4000

複製代碼

prefork
模型會為每個請求建立一個新進程。多餘的進程保持空閑,以處理傳入的請求,這縮短了啟動延遲。只要 Web 服務器出現,預先完成的配置就會立即啟動
50 個進程,並儘力保持 10 到 20 個空閑伺服器運行。進程數的硬性限制由 MaxClients
指定。儘管一個進程能夠處理許多相繼的請求,Apache 還是會取消串連數超過 4,000 以後的進程,這降低了記憶體流失的風險。

配置線程化 MPM 與之類似,不同之處只是必須確定使用多少線程和進程。Apache 文檔解釋了所有必要的參數和計算。

要經過幾次嘗試和出錯之後才能選好要使用的值。最重要的值是 MaxClients。目標在於允許足夠多的 workder 進程或線程運行,同時又不會導致伺服器進行過度的交換。如果傳入的請求超出處理能力,那麼至少滿足此值的那些請求會得到服務,其他請求被阻塞。

如果 MaxClients 過高,那麼所有客戶機都將體驗到糟糕的服務,因為 Web
伺服器會試圖換出一個進程,以使另一個進程能夠運行。而設得過低意味著可能會不必要地拒絕服務。查看高負載下啟動並執行進程數量和所有 Apache
進程所導致的記憶體佔用情況對設定這個值很有協助。如果 MaxClients 的值超過 256,必須將 ServerLimit
也設為同樣的數值,請仔細閱讀 MPM 的文檔,瞭解相關資訊。

根據伺服器的角色調優要啟動和保持閒置伺服器數量。如果伺服器僅運行 Apache,那麼可以使用適中的值,如 清單 1 所示,因為這樣就能充分利用機器。如果系統中還有其他資料庫
或伺服器,那麼就應該限制運行中的空閑伺服器的數量。

有效地使用選項和重寫

Apache 處理的每個請求都要履行一套複雜的規則,這些規則指明了 Web 服務器必須遵循的約束或特殊指令。對檔案夾的訪問可能按 IP
地址約束為某個特定檔案夾,也可配置使用者名稱和密碼。這些選項還包含處理特定檔案,例如,如果提供了一個目錄列表,該如何處理的檔案,或輸出結果是否應壓
縮。

這些配置以 httpd.conf 中容器的形式出現,例如 <Directory>,以便指定所用配置引用的是磁碟上的一個位置;再如
<Location>,表示引用是 URL 中的路徑。清單 2 展示了一個實際的 Directory 容器。

清單 2. 為根目錄應用的一個 Directory 容器

  1. <Directory />
  2.   AllowOverride None
  3.   Options FollowSymLinks
  4. </Directory>

複製代碼


清單 2 中,位於一對 Directory 和 /Directory 標記之間的配置應用於給定目錄和該目錄下的一切內容 ——
在本例中,這個給定目錄是根目錄。此處,AllowOverride
標記指出,使用者不允許重寫任何選項(稍後將進一步介紹)。FollowSymLinks 選項被啟用,它允許 Apache
查看之前的符號串連來為請求提供服務,即便檔案位於包含 Web 檔案的目錄之外。這就意味著,如果 Web 目錄中的一個檔案是
/etc/passwd 的符號串連,Web 服務器將在請求時順利為該檔案提供服務。如果使用了
-FollowSymLinks,該特性就會被禁用,同樣的請求將致使為客戶機返回錯誤。

最後這個情境正是導致兩方面關注的原因所在。第一個方面與效能有關。如果禁用了 FollowSymLinks,Apache
就必須檢查使用該檔案名稱的所有組件(目錄和檔案本身),以確保它們不是符號串連。這會帶來額外的開銷(磁碟操作)。另外一個稱為
FollowSymLinksIfOwnerMatch 的選項會在檔案所有者與串連所有者相同時使用符號串連。為獲得最佳效能,請使用 清單 2
中的選項。

至此,有安全意識的讀者應該有了警惕的感覺。安全性永遠是功能性與風險之間的權衡。在我們的例子中,功能性是速度,而風險是允許對系統上的檔案進行未經授
權的訪問。緩解風險的措施之一是 LAMP
應用伺服器通常專註於一種具體功能,使用者無法建立危險的符號串連。如果有必要啟用符號串連,那麼可以將其約束在檔案系統的特定地區,如清單 3 所示。

清單 3. 將 FollowSymLinks 約束為一個使用者的目錄

  1. <Directory />
  2.  Options FollowSymLinks
  3. </Directory>
  4. <Directory /home/*/public_html>
  5.  Options -FollowSymLinks
  6. </Directory>

複製代碼

在清單 3 中,一個使用者的主目錄中的任何 public_html 目錄及其所有子目錄都移除了 FollowSymLinks 選項。

如您所見,通過主伺服器配置,可為每個目錄單獨配置選項。使用者可以自行重寫這種伺服器配置(如果管理員通過 AllowOverrides
語句允許了這種操作),只需將一個 .htaccess 檔案放入目錄即可。該檔案包含額外的伺服器指令,每次請求包含 .htaccess
檔案的目錄時將載入並應用這些指令。儘管之前探討過系統沒有使用者的問題,但許多 LAMP 應用程式都利用這種功能性來控制訪問、實現 URL
重寫,因此有必要理解其工作原理。

即便 AllowOverrides 語句能阻止使用者去做您不希望他們做的事,Apache 也必須檢查 .htaccess
檔案,看看是否有要完成的工作。父目錄可以指定由來自子目錄的請求處理的指令,這也就表示,Apache
必須搜尋所請求檔案的分類樹的所有組件。可想而知,這會使每次請求都導致大量磁碟操作。

最簡單的解決方案是不允許重寫,這能消除 Apache 檢查 .htaccess 的需求。之後的任何特殊配置都將直接放在 httpd.conf
中。清單 4 顯示為對一個使用者的項目目錄進行密碼檢查向 httpd.conf 增加的代碼,而不是將其放入一個 .htaccess 檔案並依賴於
AllowOverrides。

清單 4. 將 .htaccess 配置移入 httpd.conf

  1. <Directory /home/user/public_html/project/>
  2.  AuthUserFile /home/user/.htpasswd
  3.  AuthName "uber secret project"
  4.  AuthType basic
  5.  Require valid-user
  6. </Directory>

複製代碼

如果配置轉移到 httpd.conf 中,且 AllowOverrides 被禁用,磁碟的使用就能減少。一個使用者的項目可能不會吸引許多人來點擊,但設想一下,將這項技術應用於一個忙碌的網站時會有多麼強大。

有時不可能徹底消除 .htaccess 檔案的使用。例如,在清單 5 中,一個選項被約束到檔案系統的特定部分,重寫也可以是有範圍的。

清單 5. 限定 .htaccess 檢查的範圍

  1. <Directory />
  2.  AllowOverrides None
  3. </Directory>
  4. <Directory /home/*/public_html>
  5.  AllowOverrides AuthConfig
  6. </Directory>

複製代碼


現清單 5 之後,Apache 會在父目錄中尋找 .htaccess 檔案,但會在 public_html
目錄處停止,因為檔案系統的其餘部分禁用了此功能。例如,如果請求的是一個映射到
/home/user/public_html/project/notes.html 的檔案,那麼僅有 public_html 和 project
目錄被搜尋。

關於每目錄單獨配置的最後一個提示就是:要按順序依次進行。任何介紹 Apache 調優的的文章都會告訴您,應通過 HostnameLookups
off 指令禁用 DNS 尋找,因為試圖反向解析串連到您的伺服器的所有 IP 位址無疑是浪費資源。然而,基於主機名稱的任何約束都會迫使 Web
伺服器對客戶機的 IP
地址執行反向尋找,對其結果進行正向尋找,以驗證該名稱的真實性。因此,避免使用基於客戶主機名稱的存取控制,在必須使用時限定其範圍,這些都是明智的做
法。

持久串連

一個客戶機串連到 Web 服務器時,允許客戶機通過同一個 TCP 串連發出多個請求,這減少了與多個串連相關的延遲。在一個 Web
頁面引用了多幅圖片時,這就很有用:客戶機可以通過一個串連先請求頁面,再請求所有圖片。其缺點在於伺服器上的 worker
進程必須等待客戶機要關閉的會話,之後才能轉到下一個請求。

Apache 使您能夠配置如何處理持久串連(稱為 keepalives)。httpd.conf 全域級的 KeepAlive 5
允許伺服器在串連強制關閉之前處理一個串連上的 5 個請求。將此值設定為 0 將禁用持久串連。同樣位於全域級上的 KeepAliveTimeout
確定在會話關閉之前,Apache 將等待另外一個串連多久。

持久串連的處理並非 “一刀切” 式的配置。對於某些 Web 網站,禁用 keepalives 更合適(KeepAlive
0);而對於其他一些網站,啟用它會帶來巨大的收益。惟一的解決之道就是嘗試使用這兩種配置,自己觀察哪種更合適。但若啟用了
keepalives,使用較小的逾時時間較為明智,例如 2,即 KeepAliveTimeout
2。這能確保希望發出另外一個請求的客戶機有充足的時間,還能確保 worker 進程不會一直空閑,等待可能永遠不會出現的下一個請求。

壓縮

Web 服務器能夠在將輸出發回給客戶機之前壓縮它。這將使通過 Internet 發送的頁面更小,代價是 Web 服務器上的 CPU
周期。對於那些負擔得起 CPU 開銷的伺服器來說,這是提高頁面下載速度的好辦法 —— 頁面壓縮後大小變為原來的三分之一這種事情並不罕見。

圖片通常已經是壓縮過的,因此壓縮應僅限於文本輸出。Apache 通過 mod_deflate 提供壓縮。儘管 mod_deflate 可輕鬆啟用,但它涉及到太多的複雜性,很多手冊都解釋了這些複雜的內容。本文不介紹壓縮的配置。

調優 PHP

PHP 是運行應用程式代碼的引擎。應該僅安裝計劃使用的那些模組,並配置您的 Web 服務器,使之僅為指令檔(通常是以 .php 結尾的那些檔案)使用 PHP,而非所有靜態檔案。

作業碼緩衝

請求一個 PHP 指令碼時,PHP 會讀取該指令碼,並將其編譯為 Zend 作業碼,這是要執行的代碼的一種二進位表示形式。隨後,此作業碼由 PHP
執行並丟棄。作業碼緩衝將儲存這個編譯後的作業碼,並在下一次調用該頁面時重用它。這會節省很多時間。有多種緩衝可用,我比較常用的是
eAccelerator。

要安裝 eAccelerator,您的電腦上需要有 PHP 開發庫。由於不同的 Linux 發布版存放檔案的位置不同,所以最好直接從
eAccelerator 的 Web 網站獲得安裝說明(參見 參考資料
部分獲得連結)。您的發布版也有可能已經包含了一個作業碼緩衝,只需安裝即可。

無論如何在系統上安裝 eAccelerator,都有一些配置選項需要注意。設定檔通常是
/etc/php.d/eaccelerator.ini。eaccelerator.shm_size
定義共用快取的大小,編譯後的指令碼就儲存在這裡。該值的單位是MB(MB)。根據您的應用程式確定恰當的大小。eAccelerator
提供了一個指令碼來顯示緩衝的狀態,其中包含記憶體佔用,64MB
是個不錯的選擇(eaccelerator.shm_size="64")。如果您選擇的值未被接受,那麼必須修改核心的最大共用記憶體的大小。向
/etc/sysctl.conf 添加 kernel.shmmax=67108864,運行 sysctl -p
來使設定生效。kernel.shmmax 值的單位是位元組。

如果共用記憶體的分配超出極限,eAccelerator 必須將舊指令碼從記憶體中清除。預設情況下,這是被禁用的;eaccelerator.shm_ttl = "60" 指定:當 eAccelerator 用完共用記憶體時,60 秒內未被訪問的所有指令碼都將被清除。

另一種流行的 eAccelerator 替代工具是 Alternative PHP Cache(APC)。Zend 的廠商也提供了一種商業作業碼緩衝,包括一個進一步提高效率的最佳化器。

php.ini

PHP 的配置是在 php.ini 中完成的。四個重要的設定控制 PHP 可使用多少系統資源,如表 1 所列。

表 1. php.ini 中與資源相關的設定

設定 描述 建議值
max_execution_time 一個指令碼可使用多少 CPU 秒 30
max_input_time 一個指令碼等待輸入資料的時間有多長(秒) 60
memory_limit 在被取消之前,一個指令碼可使用多少記憶體(位元組) 32M
output_buffering 資料發送給客戶機之前,有多少資料(位元組)需要緩衝 4096

具體數字主要取決於您的應用程式。如果要從使用者處接收大檔案,那麼 max_input_time 可能必須增加,可以在 php.ini
中修改,也可以通過代碼重寫它。與之類似,CPU
或記憶體佔用較多的程式也可能需要更大的設定值。目標就是緩解超標程式的影響,因此不建議全域禁用這些設定。關於
max_execution_time,還有一點需要注意:它表示進程的 CPU 時間,而不是絕對時間。因此一個進行大量 I/O
和少量計算的程式的已耗用時間可能遠遠超過 max_execution_time。這也是 max_input_time 可以大於
max_execution_time 的原因所在。           

PHP
可執行檔日誌記錄數是可配置的。在生產環境中,禁用除最重要的日誌以外的一切日誌記錄能夠減少磁碟寫操作。如果需要使用日誌來排除問題,那麼可以按需啟用
日誌記錄。error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR
將啟用足夠的日誌記錄,使您發現問題,同時從指令碼中消除大量無用的內容。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.