Nginx

辨識高端 VPS 的性能瓶頸(Apache 2.4 event_mpm/lighttpd/nginx)

  • February 4, 2014

我有一個來自 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>

引用自:https://serverfault.com/questions/482152