LAMP 架構html
對任何系統進行調優的第一步都是瞭解它的工做原理。按照最簡單的形式,基於 LAMP 的應用程序是用 PHP 這樣的腳本語言編寫的,它們做爲 Linux 主機上運行的 Apache Web 服務器的一部分運行。jquery
PHP 應用程序經過請求的 URL、全部表單數據和已捕獲的任意會話信息從客戶機得到信息,從而肯定應該執行什麼操做。若有必要,服務器會從 MySQL 數據庫(也在 Linux 上運行)得到信息,將這些信息與一些 Hypertext Markup Language(HTML)模板組合在一塊兒,並將結果返回給客戶機。當用戶在應用程序中導航時,這個過程重複進行;當多個用戶訪問系統時,這個過程會併發進行。可是,數據流不是單向的,由於能夠用來自用戶的信息更新數據庫,包括會話數據、統計數據(包括投票)和用戶提交的內容(好比評論或站點更新)。除了動態元素以外,還有靜態元素,好比圖像、JavaScript 代碼和層疊樣式表(CSS)。linux
在研究 LAMP 系統中的請求流以後,就來看看可能出現性能瓶頸的地方。數據庫提供許多動態信息,因此數據庫對查詢的響應延遲都會反映在客戶機中。Web 服務器必須可以快速地執行腳本,還要可以處理多個併發請求。最後,底層操做系統必須處於良好的狀態才能支持應用程序。經過網絡在不一樣服務器之間共享文件的其餘設置也可能成爲瓶頸。瀏覽器
度量性能安全
持續地對性能進行度量在兩個方面有幫助。首先,度量能夠幫助瞭解性能趨勢,包括好壞兩方面的趨勢。做爲一個簡單的方法,查看一下 Web 服務器上的中央處理單元(CPU)使用率,就能夠了解 CPU 是否負載太重。一樣,查看過去使用的總帶寬並推斷將來的變化,能夠幫助判斷何時須要進行網絡升級。這些度量最好與其餘度量和觀測結合考慮。例如,當用戶抱怨應用程序太慢時,能夠檢查磁盤操做是否達到了最大容量。服務器
性能度量的第二個用途是,判斷調優是對系統性能有幫助,仍是使它更糟糕了。方法是比較修改以前和以後的度量結果。可是,爲了進行有效的比較,每次應該只修改一個設置,而後對適當的指標進行比較以判斷修改的效果。每次只修改一個設置的緣由應該是很明顯的:同時作出的兩個修改極可能會相互影響。選擇用來進行比較的指標比較微妙。cookie
選擇的指標必須可以反映應用程序用戶感受到的響應。若是一項修改的目標是減小數據庫的內存佔用量,那麼取消各類緩衝區確定會有幫助,可是這會犧牲查詢速度和應用程序性能。因此,應該選擇應用程序響應時間這樣的指標,這會使調優向着正確的方向發展,而不只僅是針對數據庫內存使用量。網絡
能夠以許多方式度量應用程序響應時間。最簡單的方法多是使用 curl
命令,見清單 1。
$ curl -o /dev/null -s -w %{time_connect}:%{time_starttransfer}:%{time_total}\ http://www.canada.com 0.081:0.272:0.779 |
清單 1 給出對一個流行的新聞站點執行 curl
命令的狀況。輸出一般是 HTML 代碼,經過 -o
參數發送到 /dev/null
。-s
參數去掉全部狀態信息。-w
參數讓 curl
寫出表 1 列出的計時器的狀態信息:
計時器 | 描述 |
---|---|
time_connect | 創建到服務器的 TCP 鏈接所用的時間 |
time_starttransfer | 在發出請求以後,Web 服務器返回數據的第一個字節所用的時間 |
time_total | 完成請求所用的時間 |
這些計時器都相對於事務的起始時間,甚至要先於 Domain Name Service(DNS)查詢。所以,在發出請求以後,Web 服務器處理請求並開始發回數據所用的時間是 0.272 - 0.081 = 0.191 秒。客戶機從服務器下載數據所用的時間是 0.779 - 0.272 = 0.507 秒。
經過觀察 curl
數據及其隨時間變化的趨勢,能夠很好地瞭解站點對用戶的響應性。
固然,Web 站點不只僅由頁面組成。它還有圖像、JavaScript 代碼、CSS 和 cookie 要處理。curl
很適合瞭解單一元素的響應時間,可是有時候須要瞭解整個頁面的裝載速度。
用於 Firefox 瀏覽器的 Tamper Data 擴展(參見 參考資料 一節中的連接)能夠在日誌中記錄 Web 瀏覽器發出的每一個請求,並顯示每一個請求所用的下載時間。使用這個擴展的方法是,選擇 Tools > Tamper Data 來打開 Ongoing requests 窗口。裝載要考察的頁面,而後就會看到瀏覽器發出的每一個請求的狀態和裝載每一個元素所用的時間。圖 1 給出裝載 developerWorks 主頁的結果。
圖 1. 用於裝載 developerWorks 主頁的請求細目
每一行描述一個元素的裝載狀況。顯示的數據包括髮出請求的時間、裝載所用的時間、大小和結果。Duration 欄列出裝載元素自己所用的時間,Total Duration 欄列出全部子元素所用的時間。在圖 1 中,裝載主要頁面所用的時間是 516 毫秒(ms),可是裝載全部東西並顯示整個頁面所用的時間是 5101 ms。
Tamper Data 擴展有一種有用的模式,將頁面裝載數據的輸出繪製成圖形。右擊 Ongoing requests 窗口上半部分的任何地方,並選擇 Graph all。圖 2 顯示圖 1 中數據的圖形化視圖。
圖 2. 用於裝載 developerWorks 主頁的請求的圖形化視圖
在圖 2 中,每一個請求的持續時間顯示爲深藍色,並相對於頁面裝載的啓始時間顯示。因此,能夠看出哪些請求使整個頁面的裝載變慢了。
儘管關注的重點是頁面裝載時間和用戶體驗,可是也不要忽視核心系統指標,好比磁盤、內存和網絡。有許多實用程序能夠捕獲這些信息;其中最有幫助的多是 sar
、vmstat
和 iostat
。關於這些工具的更多信息,請參見 參考資料 一節。
在對系統的 Apache、PHP 和 MySQL 組件進行調優以前,應該花一些時間確保底層 Linux 組件的運行正常。還應該對正在運行的服務進行縮減,只運行須要的那些服務。這不可是一種良好的安全實踐,並且能夠節省內存和 CPU 時間。
大多數 Linux 發佈版都定義了適當的緩衝區和其餘 Transmission Control Protocol(TCP)參數。能夠修改這些參數來分配更多的內存,從而改進網絡性能。設置內核參數的方法是經過 proc
接口,也就是經過讀寫 /proc
中的值。幸運的是,sysctl
能夠讀取 /etc/sysctl.conf
中的值並根據須要填充 /proc
,這樣就可以更輕鬆地管理這些參數。清單 2 展現在互聯網服務器上應用於 Internet 服務器的一些比較激進的網絡設置。
清單 2. 包含較爲激進的網絡設置的 /etc/sysctl.conf
# Use TCP syncookies when needed net.ipv4.tcp_syncookies = 1 # Enable TCP window scaling net.ipv4.tcp_window_scaling: = 1 # Increase TCP max buffer size net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 # Increase Linux autotuning TCP buffer limits net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 # Increase number of ports available net.ipv4.ip_local_port_range = 1024 65000 |
將這些設置添加到 /etc/sysctl.conf
的現有內容中。第一個設置啓用 TCP SYN cookie。當從客戶機發來新的 TCP 鏈接時,數據包設置了 SYN 位,服務器就爲這個半開的鏈接建立一個條目,並用一個 SYN-ACK 數據包進行響應。在正常操做中,遠程客戶機用一個 ACK 數據包進行響應,這會使半開的鏈接轉換爲全開的。有一種稱爲 SYN 氾濫(SYN flood) 的網絡***,它使 ACK 數據包沒法返回,致使服務器用光內存空間,沒法處理到來的鏈接。SYN cookie 特性能夠識別出這種狀況,並使用一種優雅的方法保留隊列中的空間(細節參見 參考資料 一節)。大多數系統都默認啓用這個特性,可是確保配置這個特性更可靠。
啓用 TCP 窗口伸縮使客戶機可以以更高的速度下載數據。TCP 容許在未從遠程端收到確認的狀況下發送多個數據包,默認設置是最多 64 KB,在與延遲比較大的遠程客戶機進行通訊時這個設置可能不夠。窗口伸縮會在頭中啓用更多的位,從而增長窗口大小。
後面四個配置項增長 TCP 發送和接收緩衝區。這使應用程序能夠更快地丟掉它的數據,從而爲另外一個請求服務。還能夠強化遠程客戶機在服務器繁忙時發送數據的能力。
最後一個配置項增長可用的本地端口數量,這樣就增長了能夠同時服務的最大鏈接數量。
在下一次引導系統時,或者下一次運行 sysctl -p /etc/sysctl.conf
時,這些設置就會生效。
磁盤在 LAMP 架構中扮演着重要的角色。靜態文件、模板和代碼都來自磁盤,組成數據庫的數據表和索引也來自磁盤。對磁盤的許多調優(尤爲是對於數據庫)集中於避免磁盤訪問,由於磁盤訪問的延遲至關高。所以,花一些時間對磁盤硬件進行優化是有意義的。
首先要作的是,確保在文件系統上禁用 atime
日誌記錄特性。atime
是最近訪問文件的時間,每當訪問文件時,底層文件系統必須記錄這個時間戳。由於系統管理員不多使用 atime
,禁用它能夠減小磁盤訪問時間。禁用這個特性的方法是,在 /etc/fstab
的第四列中添加 noatime
選項。清單 3 給出了一個配置示例。
清單 3. 演示如何啓用 noatime
的 fstab 示例
/dev/VolGroup00/LogVol00 / ext3 defaults,noatime 1 1 LABEL=/boot /boot ext3 defaults,noatime 1 2 devpts /dev/pts devpts gid=5,mode=620 0 0 tmpfs /dev/shm tmpfs defaults 0 0 proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 LABEL=SWAP-hdb2 swap swap defaults 0 0 LABEL=SWAP-hda3 swap swap defaults 0 0 |
在清單 3 中只修改了 ext3 文件系統,由於 noatime
只對駐留在磁盤上的文件系統有幫助。爲讓這一修改生效,不須要從新引導;只需從新掛裝每一個文件系統。例如,爲了從新掛裝根文件系統,運行 mount / -o remount
。
有多種磁盤硬件組合,並且 Linux 不必定可以探測出訪問磁盤的最佳方式。可使用 hdparm
命令查明和設置用來訪問 IDE 磁盤的方法。hdparm -t /path/to/device
執行速度測試,能夠將這個測試結果做爲性能基準。爲了使結果儘量準確,在運行這個命令時系統應該是空閒的。清單 4 給出在 hda
上執行速度測試的結果。
# hdparm -t /dev/hda /dev/hda: Timing buffered disk reads: 182 MB in 3.02 seconds = 60.31 MB/sec |
這一測試說明,在這個磁盤上讀取數據的速度是大約每秒 60 MB。
在嘗試一些磁盤調優選項以前,必須注意一個問題。錯誤的設置可能損害文件系統。有時候會出現一個警告,指出這個選項與硬件不兼容;可是,有時候沒有警告消息。所以,在將系統投入生產以前,必須對設置進行完全的測試。在全部服務器上都採用標準的硬件也會有所幫助。
表 2 列出比較經常使用的一些選項。
選項 | 描述 |
---|---|
-vi | 向磁盤查詢它支持的設置以及它正在使用的設置。 |
-c | 查詢/啓用 (E)IDE 32 位 I/O 支持。hdparm -c 1 /dev/hda 啓用這個設置。 |
-m | 查詢/設置每中斷多扇區模式。若是設置大於零,設置值就是每一箇中斷能夠傳輸的最大扇區數量。 |
-d 1 -X | 啓用直接內存訪問(DMA)傳輸並設置 IDE 傳輸模式。hdparm 手冊頁詳細說明了在 -X 後面能夠設置的數字。只有在 -vi 說明目前並未使用最快速的模式的狀況下,才須要進行這個設置。 |
不幸的是,對於 Fiber Channel and Small Computer Systems Interface(SCSI)系統,調優依賴於具體的驅動器。
必須將有幫助的設置添加到啓動腳本中,好比 rc.local
。
網絡文件系統(NFS)是一種經過網絡共享磁盤的方法。NFS 能夠幫助確保每一個主機具備相同數據的拷貝,並確保修改反映在全部節點上。可是,在默認狀況下,NFS 的配置不適合大容量磁盤。
每一個客戶機應該用 rsize=32768,wsize=32768,intr,noatime
掛裝遠程文件系統,從而確保:
atime
。
能夠將這些設置放在 /etc/fstab
中,見 清單 3。若是使用自動掛裝器,那麼應該將這些設置放在適當的 /etc/auto.*
文件中。
在服務器端,必定要確保有足夠的 NFS 內核線程來處理全部客戶機。在默認狀況下,只啓動一個線程,可是 Red Hat 和 Fedora 系統會啓動 8 個線程。對於繁忙的 NFS 服務器,應該提升這個數字,好比 32 或 64。能夠用 nfsstat -rc
命令評估客戶機,瞭解是否有阻塞的現象,這個命令顯示客戶機遠程過程調用(RPC)統計數據。清單 5 顯示一個 Web 服務器的客戶機統計數據。
# nfsstat -rc Client rpc stats: calls retrans authrefrsh 1465903813 0 0 |
第二列 retrans
是零,這表示從上一次從新引導以來沒有出現須要從新傳輸的狀況。若是這個數字比較大,就應該考慮增長 NFS 內核線程。設置方法是將所需的線程數量傳遞給 rpc.nfsd
,好比 rpc.nfsd 128
會啓動 128 個線程。任什麼時候候均可以進行這種設置。線程會根據須要啓動或銷燬。一樣,這個設置應該放在啓動腳本中,尤爲是在系統上啓用 NFS 的腳本。
關於 NFS,最後要注意一點:若是可能的話,應該避免使用 NFSv2,由於 NFSv2 的性能比 v3 和 v4 差得多。在現代的 Linux 發行版中這應該不是問題,可是能夠在服務器上檢查 nfsstat
的輸出,瞭解是否有任何 NFSv2 調用。