2011-05-27 46 views
6

我目前正在測試我放在一起的服務器設置的負載能力。 apache2服務器上安裝了PHP 5.X,並且它連接到單獨計算機上的主數據庫,然後連接2個從服務器中的1個進行讀取。PHP生成頁面,但沒有立即將它們返回給用戶

如果我自己調用它,我的測試頁需要0.2秒才能生成。我在不同的服務器上創建了一個php腳本,可以同時創建65個測試頁面。測試頁面會在整個頁面中使用microtime基準測試,讓我知道每個部分正在使用多長時間。正如所料 - 至少對我來說,如果任何人對此有任何意見或建議,請隨時評論,那麼頁面的SQL部分需要一小段時間才能收到第一對請求,然後降級,因爲其餘部分查詢堆積起來,必須等待。我認爲這可能是磁盤IO問題,但在固態驅動器上測試時會出現同樣的情況。

我的問題是,65個頁面中大約30個左右的頁面被創建,並且按照我的預期被我的測試腳本加載。我的基準測試表明,該頁面是在3秒內創建的,而我的測試腳本表示它在3.1秒內完全收到頁面。差別不大。問題是,對於其他請求,我的基準測試表示頁面在3秒內加載完畢,但測試腳本在6秒之前沒有完整收到頁面。這是由apache服務器生成的頁面之間的整整3秒鐘,併發送回我的測試腳本請求它。爲了確保它不是測試腳本的問題,我嘗試在本地瀏覽器運行時加載頁面,並在Chrome中通過時間線窗口收到相同的延遲。

我已經嘗試了Apache的各種配置,但似乎無法找到造成這種延遲的原因。我最近的嘗試如下。該機器是一款四核AMD 2.8Ghz,內存爲2Ghz。任何幫助配置,或其他建議,如何做,將不勝感激。 - 對於長期問題抱歉。

我應該提到,我在腳本運行時監視了資源,並且CPU的負載最高達到了9%,並且總是至少有1個ram空閒。

我還會提到,當我查詢的所有內容都是靜態HTML頁面時,就會發生同樣類型的事情。第一對夫婦需要X秒,然後慢慢增加到3秒。

LockFile ${APACHE_LOCK_DIR}/accept.lock 
PidFile ${APACHE_PID_FILE} 
Timeout 120 
MaxClients   150 
KeepAlive On 
KeepAliveTimeout 4 
MaxKeepAliveRequests 150 

Header always append x-frame-options sameorigin 

    StartServers   50 
    MinSpareServers  25 
    MaxSpareServers  50 
    MaxClients   150 
    MaxRequestsPerChild 0 


User ${APACHE_RUN_USER} 
Group ${APACHE_RUN_GROUP} 
AccessFileName .httpdoverride 

    Order allow,deny 
DefaultType text/plain 
HostnameLookups Off 
ErrorLog ${APACHE_LOG_DIR}/error.log 
LogLevel warn 
Include mods-enabled/*.load 
Include mods-enabled/*.conf 
Include httpd.conf 
Include ports.conf 

LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined 
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined 
LogFormat "%h %l %u %t \"%r\" %>s %O" common 
LogFormat "%{Referer}i -> %U" referer 
LogFormat "%{User-agent}i" agent 
Include conf.d/ 
Include sites-enabled/ 
AddType application/x-httpd-php .php 
AddType application/x-httpd-php-source .phps 



    SecRuleEngine On 
    SecRequestBodyAccess On 
    SecResponseBodyAccess Off 
    SecUploadKeepFiles Off 
    SecDebugLog /var/log/apache2/modsec_debug.log 
    SecDebugLogLevel 0 
    SecAuditEngine RelevantOnly 
    SecAuditLogRelevantStatus ^5 
    SecAuditLogParts ABIFHZ 
    SecAuditLogType Serial 
    SecAuditLog /var/log/apache2/modsec_audit.log 
    SecRequestBodyLimit 131072000 
    SecRequestBodyInMemoryLimit 131072 
    SecResponseBodyLimit 524288000 
     ServerTokens Full 
     SecServerSignature "Microsoft-IIS/5.0" 

UPDATE: 看來很多的響應正專注於一個事實,即SQL是罪魁禍首。所以我在這裏指出,同樣的行爲發生在一個靜態的HTML頁面上。基準測試的結果列在下面。

 
Concurrency Level:  10 
Time taken for tests: 5.453 seconds 
Complete requests:  1000 
Failed requests:  899 
    (Connect: 0, Receive: 0, Length: 899, Exceptions: 0) 
Write errors:   0 
Total transferred:  290877 bytes 
HTML transferred:  55877 bytes 
Requests per second: 183.38 [#/sec] (mean) 
Time per request:  54.531 [ms] (mean) 
Time per request:  5.453 [ms] (mean, across all concurrent requests) 
Transfer rate:   52.09 [Kbytes/sec] received 

Connection Times (ms) 
       min mean[+/-sd] median max 
Connect:  0 21 250.7  0 3005 
Processing: 16 33 17.8  27  138 
Waiting:  16 33 17.8  27  138 
Total:   16 54 253.0  27 3078 

Percentage of the requests served within a certain time (ms) 
    50%  27 
    66%  36 
    75%  42 
    80%  46 
    90%  58 
    95%  71 
    98%  90 
    99% 130 
100% 3078 (longest request) 

我還會說我通過使用PHP和microtime()確定頁面正在生成之前發生滯後。我通過生成頁面和接收它的測試腳本之間的時間差異來確定這一點。差異是一致的,這意味着從頁面生成點到我的測試頁收到的點的時間長度相同,無論整個請求花了多長時間。

謝謝所有回覆。一切都很好,我不能說他們中的任何一個都解決了這個問題。

+0

嘗試更高的StartServers和MinSpareServers。根據我的經驗,當apache突然爆發流量時,可能需要一段時間才能啓動額外的線程。在宏偉的方案中,通過快速反向代理(nginx)進行代理以更快地響應連接並更快地釋放apache線程。更好的是,使用魷魚/清漆緩存頁面,這樣您就不會浪費資源生成幾百次完全相同的內容。 – 2011-05-27 18:55:58

+0

啊,剛剛注意到了關於數據庫的一點。 1)儘可能避免寫入2)確定哪些查詢正在減速3)緩存以完全避免數據庫訪問。我會做一些基準測試 - 爲每個查詢記錄查詢時間,並生成所有查詢運行的列表,在請求期間從最慢到最快排序。 – 2011-05-27 19:00:35

+0

好問題,只屬於不同的網站。 – 2011-05-27 19:01:07

回答

1

什麼是確切下降之前加載的頁面數量?您提到您正在從單個外部腳本創建65個併發請求。你沒有像啓用limitipconn那樣的mod,這會限制N從單個IP或其他東西連接後的情況?它總是正好30(或其他)連接,然後延遲?

+0

它在下降之前總是隨機的。如果我縮減同時發生的請求,有時會在需要3秒鐘之前耗用1000頁的負載。 – Andrew 2011-06-14 23:13:46

2

還有很多其他的因素,但我真的猜測你正在使用30M左右的速度快速產生30-40個進程,並且殺死你的機器有限的內存,然後繼續產生新的進程並進行交換,放慢一切。

由於內存爲2G,MaxClients爲150,MaxRequestsPerChild爲0,即使您的數據庫不在同一臺物理服務器上,服務器資源也可能會淹沒。

基本上,對於Web服務器的性能,你不想交換。運行你的測試,然後立即用網絡服務器檢查內存:

free -m 

這會給你MB和交換使用的內存使用情況。理想情況下,您應該看到交換爲0或接近0.如果交換使用率不爲零或非常低,則問題僅僅是內存用完,服務器出現抖動,因此會浪費CPU,導致響應速度變慢。

你需要確定一些數字,但首先做一個'頂部',然後在頂部運行時按下Shift-M按內存排序。下一次運行測試並查找每個httpd進程報告%MEM的百分比。它會有所不同,因此最好使用較高的那個作爲最差情況下的指導。我在同一臺服務器上有一個wordpress,一個drupal和一個custome站點,每個http進程從開始就按例分配20M,並最終增長時間 - 如果每次都不超過100M,那麼最終會增長。

從我的屁股中拉出一些數字,例如,如果我有2G和linux,核心服務和mysql使用800M,我會一直對我希望可用於Apache樂趣的內存持有期望1G。有了這個,如果我的apache進程平均使用20M,我只能有50個MaxClients。這是一個非常不保守的數字,在現實生活中我會將Max降至40左右以保證安全。不要試圖捏造內存......如果你的服務器擁有足夠的流量來同時擁有40個連接,那麼在升級Max服務器之前,請花100美元去4G。這是其中之一,一旦你穿過線路,所有的東西都在廁所裏,所以要安全地保持在你的記憶極限!

另外,用PHP我喜歡保持MaxRequestsPerChild爲100左右...你不是CPU綁定服務的網頁,所以不要擔心節省幾毫秒產卵新的子進程。將其設置爲0意味着無限制的請求,並且除非總客戶端超過MaxSpareServers,否則它們不會被終止。這通常是一個非常壞的事情與PHP使用Apache的工人,因爲他們只是不斷增長,直到發生壞事(如不得不硬盤重啓你的服務器,因爲你無法登錄,因爲Apache用盡所有內存和SSH無法正常工作沒有超時)。

祝你好運!

+0

我不認爲它進入交換,我正在監視使用情況。現在我已經獲得了4個RAM,所以當我有時間查看結果是否有所不同時,我會重複這些測試。 – Andrew 2011-06-24 12:07:02

相關問題