Apache 握手在 prefork 配置上很慢,需要配置調整
我的伺服器執行 Ubuntu 14/Apache2.4.7,有一個 htaccess 重定向來強制所有請求使用 HTTPS。一般來說,它反應很快。但是,我最近更改了我的 SSL 配置,以限制用於更現代設置的密碼,以防止心臟出血、野獸和其他漏洞,並確保使用現代加密方法。
我最近收到了一些抱怨——這些抱怨似乎與這些變化無關(見下文)——我的機器有時會很慢。這些投訴表明它可能與握手或建立連接有關:
根據所使用的瀏覽器,我一直在間歇性地緩慢載入帶有各種瀏覽器狀態消息的頁面;一切都是為了等待建立安全連接。
我寫了一個使用 cURL 連接一千次的 PHP 腳本。我昨晚很晚才執行它,緩慢似乎不是問題。我嘗試連接到 https 和 http 並遵循上面的重定向。所有請求在 3.5 秒或更短時間內完成,絕大多數 (96-98%) 在不到 1.5 秒內完成。
我在加州時間今天早上 10:30 執行了相同的腳本,大約 10% 的請求花費了超過 1.5 秒的時間,許多請求花費的時間更多。最長的時間約為 17 秒。
我的研究和直覺告訴我,雖然 https 握手比 http 連接更複雜,但這個問題可能可以通過調整我的 apache 配置(例如MaxRequestWorker)設置來解決。伺服器幾乎從不超過 1.5 左右的平均負載,看起來有足夠的可用記憶體。
誰能建議我如何縮小這裡的瓶頸以及我可以採取哪些步驟來解決它?任何幫助將非常感激。
編輯:我訪問了#apache IRC 頻道並在那裡詢問,友好的人們提請我注意這個伺服器處於prefork模式並且 MinSpareServers、MaxSpareServers、StartServers 和 MaxRequestWorkers 都是預設或調整但仍然很低的事實.
他們非常堅持生產伺服器不應該使用 prefork 模式,並向我推薦了一些連結:
- Apache MPM Event - 描述 apache 事件模式
- 在 Apache httpd 上執行 PHP - 在 Apache 上執行 php 的選項列表
- openssl_seal()、PHP 和 Apache2handle 的故事- 對 php 漏洞利用的描述
據我了解,這些性能問題的更正解決方案可能是安裝 apache 以在事件模式下執行,但我的網站很複雜,並且使用了一些程序分叉之類的東西。我希望作為權宜之計的解決方案,有些人可以建議對minSpareServers、maxSpareServers、startServers、maxRequestWorker進行調整
編輯 2: 一個典型的慢請求的細分,由
curl_getinfo
PHP 中的函式報告:elapsed: 17.6722049713 ssl_verify_result: 0 total_time: 17.671187 namelookup_time: 0.000051 connect_time: 0.065855 pretransfer_time: 16.787012 starttransfer_time: 17.340403 redirect_time: 0.261569
事實證明,Ubuntu 安裝 apache 和 php7 的軟體包似乎除了 prefork 之外沒有提供任何東西,這*真的很糟糕。*在這種情況下,我不得不使用 prefork,這根本不是理想的解決方案,但在我獲得有關使推薦配置之一正常工作的更多資訊之前,這是我唯一的選擇。
我編輯了文件/etc/apache2/mods-available/mpm_prefork.conf:
sudo nano /etc/apache2/mods-available/mpm_prefork.conf
並將 MaxRequestWorkers 設置增加到 300。請注意,為了讓我這樣做,我還必須添加 300 的 ServerLimit 設置,否則 MaxRequestWorkers 被限制為 ServerLimit 的預設值,即 256:
StartServers 5 MinSpareServers 5 MaxSpareServers 10 # changed in response to slow connect/handshaking time complaints ServerLimit 300 # note this value is constrained by ServerLimit, which defaults to 256 MaxRequestWorkers 300 MaxConnectionsPerChild 0
這些設置似乎緩解了緩慢。我在一天中的繁忙時間使用了我的 PHP 測試腳本,所有請求在 3.5 秒或更短的時間內完成,絕大多數在 1.5 秒內完成。我還使用 apache bench 和高並發值進行了測試,我可以看到伺服器通過生成 worker 進行響應,但我仍然有大量可用 RAM:
ab -n 1000 -c 100 "https://example.com/"
我檢查了 RAM:
free -h
這似乎目前正在工作,儘管我無法讓 apache 使用 ubuntu 安裝程序使用 fastCGI,這非常令人失望。