辨識高端 VPS 的性能瓶頸(Apache 2.4 event_mpm/lighttpd/nginx)
我有一個來自 vpsblast(他們的 SSD13)的高端 VPS——4 核、16gb RAM、1GigE Internet 主幹上的 320gb SSD 硬碟空間(幾乎沒有爭議)。據我所知,它正在執行 OpenVZ(使用 simfs,存在 user_beancounters)。數據庫位於同一數據中心的不同節點上,我正在執行 php-fpm,但此測試涉及靜態 9.49kb 圖像(因為 php-fpm 正在執行並且應用程序非常優化)。所有請求都通過 https,所以我執行了 http 和 https 測試來確定 SSL 是否是問題所在,但我不相信這是問題所在。作業系統是 Ubuntu 12.04 LTS。我已經測試了 apache 2.4(使用 event_mpm)、nginx 和 lighttpd,並且我看到這三者的性能非常相似,這讓我相信問題不是 httpd。我目前正在使用 apache 2。4 這些問題的目的。我在靜態對像上的性能峰值約為 400rps(每秒請求數)。這就像 3.7Mbps,遠低於 1GigE 線路的限制。
所以第一個問題:我應該在這種設置上看到什麼性能?在 FreeNode 上 #apache 的討論中,有人建議 10k 並發不應該是不可能的,我應該能夠每秒處理 10k 個請求。這些期望不合理嗎?
下一個問題是關於辨識性能瓶頸。老實說,我不知道從哪裡開始尋找,因為一切看起來都很好(我已經包含了下面頂部的螢幕截圖)。我沒有對 sysctl 進行任何調整,因為它們似乎主要由主機作業系統控制。我在 /etc/security/limits.conf 中增加了軟硬 ulimit:
www-data hard nofile 1048576 www-data soft nofile 1048576 root hard nofile 1048576 root soft nofile 1048576
我的 apache httpd.conf 對於 2.4 來說是相當標準的,但這裡是我所做的更改:
DocumentRoot "/var/www" <Directory "/var/www"> Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> <IfModule ssl_module> SSLRandomSeed startup builtin SSLRandomSeed connect builtin </IfModule> <IfModule setenvif_module> BrowserMatch "MSIE 10.0;" bad_DNT </IfModule> <IfModule headers_module> RequestHeader unset DNT env=bad_DNT </IfModule> <IfModule mod_deflate.c> SetOutputFilter DEFLATE </IfModule> # Netscape 4.x has some problems… BrowserMatch ^Mozilla/4 gzip-only-text/html # Netscape 4.06-4.08 have some more problems BrowserMatch ^Mozilla/4\.0[678] no-gzip # MSIE masquerades as Netscape, but it is fine BrowserMatch \bMSIE !no-gzip !gzip-only-text/html # Don’t compress already-compressed files SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary SetEnvIfNoCase Request_URI .(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary SetEnvIfNoCase Request_URI .(?:avi|mov|mp3|mp4|rm|flv|swf|mp?g)$ no-gzip dont-vary SetEnvIfNoCase Request_URI .pdf$ no-gzip dont-vary Header append Vary User-Agent env=!dont-var ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/$1 SSLEngine on SSLOptions +StrictRequire SSLProtocol -all +TLSv1 +SSLv3 SSLCipherSuite ALL:!kEDH:!ADH:!SSLv2:!EXPORT56:!EXPORT40:!RC4:!DES:+HIGH:+MEDIUM:+EXP SSLRandomSeed startup file:/dev/urandom 1024 SSLRandomSeed connect file:/dev/urandom 1024 SSLSessionCache "shmcb:/usr/local/apache2/logs/ssl_scache(512000)" SSLSessionCacheTimeout 300 # Masked keys for privacy:) SSLCertificateFile /usr/local/apache2/conf/xxxxx.crt SSLCertificateKeyFile /usr/local/apache2/conf/xxxxx.key SSLVerifyClient none SSLProxyEngine off <IfModule mime.c> AddType application/x-x509-ca-cert .crt AddType application/x-pkcs7-crl .crl </IfModule> SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0 ServerTokens Prod Timeout 300 KeepAlive Off <IfModule mpm_event_module> StartServers 5 MaxClients 1024 MinSpareThreads 50 MaxSpareThreads 150 ThreadLimit 64 ThreadsPerChild 64 MaxRequestsPerChild 20000 ListenBacklog 4096 </IfModule>
我不認為這是 OpenVZ 配置中的限制,因為這裡是 user_beancounters 的輸出(限制相當高)
Version: 2.5 uid resource held maxheld barrier limit failcnt 1592: kmemsize 83776469 113721344 2369781760 2606759936 0 lockedpages 4161 10616 578560 578560 0 privvmpages 670407 2743929 9223372036854775807 9223372036854775807 0 shmpages 5770 7450 1048576 1048576 0 dummy 0 0 0 0 0 numproc 233 1044 3560 3560 0 physpages 157907 290092 0 4194304 0 vmguarpages 0 0 4194304 9223372036854775807 0 oomguarpages 49397 83795 4194304 9223372036854775807 0 numtcpsock 23 1317 57330 57330 0 numflock 4 11 32768 36045 0 numpty 2 9 256 256 0 numsiginfo 1 30 256 256 0 tcpsndbuf 512360 31732952 293529600 440294400 0 tcprcvbuf 376832 21577728 293529600 440294400 0 othersockbuf 52400 360896 146764800 293529600 0 dgramrcvbuf 0 6936 14676480 14676480 0 numothersock 61 95 57330 57330 0 dcachesize 28028491 50196571 457560436 503316480 0 numfile 918 2315 655360 655360 0 dummy 0 0 0 0 0 dummy 0 0 0 0 0 dummy 0 0 0 0 0 numiptent 24 24 8448 8448 0
在辨識性能問題方面,這裡有一張性能數據相冊——前兩張圖片是 blitz.io 測試中途的 ATOP 輸出,然後在最大負載下接近尾聲。第三張圖片是 blitz.io 報告。對於相同的靜態對象,第四和第五是相同的(ATOP+blitz.io 報告),但禁用了 SSL。blitz.io 測試在 60 秒內從 1 次並發到 1000 次並發。雖然啟用 SSL 有顯著的成本,但我仍然沒有接近我期望的性能 - 增加 blitz.io 上的並發性會使事情變得更糟。所以,我把這留給你的智慧,請隨時要求任何澄清並建議任何更改讓我嘗試重新測試:)
由於事件 MPM 依賴於底層工作配置 - 嘗試以下配置作為限制實驗,然後如果更改導致可測量的差異,則意味著這至少是瓶頸之一。然後可以進一步調整:
這些是 Apache 預設值:
- ServerLimit 16 - 您可以在您發送的圖像中看到這一點 - 更改為 50
- StartServers 2 - 這是用於初始啟動 - 更改為 5
- MaxClients 150 - 將此更改為 300
- MinSpareThreads 25 - 更改為 50
- MaxSpareThreads 75 - 更改為 150
- ThreadsPerChild 25 - 更改為 50
由於我們的變化是 2-3 倍,您應該會看到大約相同倍數的線性改進。
編輯 - 改進的配置 - MaxClients(現在稱為 MaxRequestWorkers)是瓶頸。一旦伺服器實際上可以接受一定數量的客戶端,那麼只需確保子程序和每個子執行緒的數量不超過該數量。
<IfModule mpm_event_module> StartServers 5 ServerLimit 32 MinSpareThreads 64 MaxSpareThreads 128 ThreadsPerChild 64 ThreadLimit 64 MaxRequestWorkers 2048 MaxRequestsPerChild 20000 ListenBacklog 4096 </IfModule>