摘要:服務器市場份額。子進程負責創建由指令設置的服務器線程,同時還負責監聽接收到的請求,并將請求分發給處理線程。在版本引入了模塊,這個模塊基于模塊創建的,并加入了獨立的監聽線程來管理請求處理完成后的休眠的連接?;谑录姆掌魍陝?。
譯文首發于 Apache 與 Nginx 性能對比:Web 服務器優化技術,轉載請注明出處。
多年前 Apache 基金會 Web 服務器 簡稱「Apache」,由于使用者眾多幾乎等同于「Web 服務器」。httpd(含義是簡單的 http 進程)是它在 Linux 系統上的守護進程 - 同時它被預裝到主流的 Linux 發行版中。
Apache 初版于 1995 年發布,它在 維基百科 描述如下,「它在萬維網(WWW)發展初期發揮了至關重要的作用」。從 W3techs 統計結果來看,它依然是最常用的 Web 服務器軟件。不過,依據 過去十年的發展趨勢 和 與其它服務器解決方案比較 的報告的結果來分析,不難發現它的市場份額正在逐年下降。盡管,Netcraft 和 Builtwith 這兩家提供的報告略有不同,但不得不承認 Apache 市場份額的縮減與 Nginx 服務器份額在增長這一事實。
Nginx 讀作「engine x」- 由 Igor Sysoev 在 2004 年發布,最初的愿景就是取代 Apache 在 Web 服務器市場上的領導地位。在 Nginx 的網站上有一篇值得一讀的 文章,對兩款服務器進行了比較。一開始 Nginx 只是作為 Apache 某些功能的補充,主要提供靜態文件服務支持。得益于它積極的擴展在 Web 服務器領域相關功能的全方位支持,這使得它能夠穩步增長。
Nginx 通常被用作 反向代理、負載均衡 和 HTTP 緩存 服務器。CDN 和 視頻提供商使用它來構將性能強勁的內容分發系統(CDN: content delivery system)。
Apache 在其不短的發展歷程中,提供了許多 有用的模塊。眾所周知管理 Apache 服務器對開發者極其友好。動態模塊加載 能夠在無需重新編譯主服務器文件的基礎上,將模塊編譯并添加到 Apache 擴展中。通常,這些模塊位于 Linux 發行版倉庫中,在使用系統包管理器安裝后,便可以通過諸如 a2enmod 這樣的命令,將其添加到擴展中。Nginx 服務器到目前為止,依然無法靈活的實現動態添加模塊的功能。當我們閱讀 如何在 Nginx 服務器設置 HTTP/2 指南 時,你就會發現模塊需要在構建 Nginx 時,通過設置參數選項,才能將其添加進 Nginx 服務器。
另一個讓 Apache 保持住市場份額的功臣就是 .htaccess 重寫文件。它就像 Apache 服務器的萬金油一樣,使其成為共享托管技術的首選方案,因為 .htaccess 重寫支持在目錄級別上控制服務器配置。在 Apache 服務器上的每個目錄都能夠配置自己的 .htaccess 文件。
在這點上 Nginx 不僅沒有相應的解決方案,而且由于重寫性能低、命中率不高而 不被推薦。
1995–2005 Web 服務器市場份額。 數據由 Netcraft 提供
LiteSpeed 即 LSWS 是 Web 服務器市場的另一個競爭者,它兼具 Apache 的靈活性與 Nginx 的性能。支持 Apache 風格的 .htaccess、mode_security 和 mode_rewrite 模塊,另外它還支持共享設置。它的設計初衷是替代 Apache 服務器,并且能夠和 cPanel 和 Plesk 組合使用。從 2015 年開始提供 HTTP/2 支持。
LiteSpeed 有三個版本,OpenLiteSpeed、LSWS 保準版和 LSWS 企業版。標準版和企業版還提供了可選的 緩存解決方案,它可以和 Varnish 與 LSCache 一較長短。LSCache 是服務器內置的緩存解決方案,通過 .htaccess 重寫規則配置進行控制。并且,它還提供了內置預防 DDoS 攻擊的解決方案。這個功能同它的事件驅動架構設計一起成為這款服務器的競爭力保障,不僅能夠滿足以 性能為導向的服務提供商需求,還能兼顧小型服務器或網站架設市場。
硬件考量(Hardware Considerations)當我們優化系統時,我們無法忽視硬件配置。無論選擇哪種解決方案,我們都需要擁有足夠的 RAM,這點至關重要。當 Web 服務器進程或類似 PHP 解釋器程序無可用的 RAM 時,它們就會進行交換(swapping)即需要使用硬盤來補充 RAM 內存的不足。這會導致每當訪問這塊內存區域時都會帶來訪問延遲。于是便引出了第二個優化點 - 硬盤。使用 SSD 固態硬盤來構建網站是提升性能的又一關鍵。此外,我們還應考慮 CPU 可用性和服務器數據中心同目標用戶的距離。
想要深入研究硬件優化方法,可以查看 Dropbox 的好文。
監控(Monitoring)htop 是一個監控當前服務器性能及每個進程詳細信息的實用工具,它能夠在 Linux、Unix 和 macOS 系統上運行,并為我們以不同顏色區分出不同的進程狀態。
其它的監控工具如 New Relic,提供全套的監控解決方案;Netdata 一款開源的監控解決方案,兼具擴展性、細粒度指標和可定制的 Web 儀表盤,適用于小型的 VPS 系統和網絡服務器的監控。它可以通過郵件、Slack、pushbullet、Telegram 和 Twilio 等方式給任何應用或系統進程發送警告消息。
Monit 是另一款開源的系統監控工具,可以通過配置在重啟進程、重啟系統或任何我們關心事件時給我們的發送提示信息。
系統測試(Testing the System)AB - Apache Benchmark - 是一款有 Apache 基金會提供的簡單的壓測工具,其它壓測工具還有 Siege。這篇文章 詳細講解了如何同時安裝這兩款工具,可以閱讀 這篇文章 學習 AB 工具的高級使用技巧,如果需要研究 Siege 可以閱讀 此文。
如果你鐘愛 Web 應用,可以使用 Locust 這款基于 Python 的測試工具,一樣可以很方便的對網站進行性能測試。
在安裝完成 Locust 后,我們需要在項目的根目錄下創建一個 locusfile:
from locust import HttpLocust, TaskSet, task class UserBehavior(TaskSet): @task(1) def index(self): self.client.get("/") @task(2) def shop(self): self.client.get("/?page_id=5") @task(3) def page(self): self.client.get("/?page_id=2") class WebsiteUser(HttpLocust): task_set = UserBehavior min_wait = 300 max_wait = 3000
然后使用如下命令啟動服務:
locust --host=https://my-website.com
使用壓測工具時需要注意:這些工具可能造成 DDoS 攻擊,所以需要在測試網站時進行限制。
Apache 優化技術(Tuning Apache) Apache 的 mpm 模塊Apache 可以追溯到 1995 年和互聯網的早期階段,當時的服務器將接收的 HTTP 請求傳入到 TCP 連接上并重新生成一個新進程并響應這個請求。當眾多的請求被接收,也就意味著需要創建處理它們的 worker 進程。由于創建新 worker 進程的系統開銷巨大,所以 Apache 服務器的技術人員設計了 prefork 模式,并預先生成多個 worker 進程解決重新創建的問題。不過將每個進程嵌入到動態語言的解釋器(如 mod_php)中依然造成大量的資源消耗,這使得 Apache 服務器經常會出現 服務器崩潰 的問題。這是因為單個 worker 進程只能同時處理一個連接。
這個模塊在 Apache 的 MPM 系統中稱為 mpm_prefork_module。從 Apache 官網可以了解到,這個模塊僅需極少的 配置 即可完成工作,因為它能夠自動調整,其中最關鍵的是將 MaxRequestWorkers 指令值配置的足夠大,這樣可以處理更多的請求,但是還需要保證有每個 worker 進程有足夠的物理 RAM 可用。
上面的 Locust 壓測顯示 Apache 創建了大量的進程來處理請求。
不得不說,這個模塊是 Apache 聲名狼藉的罪魁禍首,它可能導致資源利用率低下的問題。
在 Apache 第二版中引入了兩個新的 MPM 模塊,試圖解決 prefork 模式所帶來的問題。即 worker 模塊 或曰 mpm_worker_module 以及 event 模塊。
worker 模塊不再基于進程模型,而是一種混合了進程-線程(process-thread)處理模式。下面引用自 Apache 官網:
單個進程(父進程)負責啟動子進程(worder 進程)。子進程負責創建由 ThreadsPerChild 指令設置的服務器線程,同時還負責監聽接收到的請求,并將請求分發給處理線程。
這種模式能提升資源利用率。
在 2.4 版本 Apache 引入了 - event 模塊,這個模塊基于 worker 模塊創建的,并加入了獨立的監聽線程來管理 HTTP 請求處理完成后的休眠的 keepalive 連接。它是一種異步非阻塞模型,內存占用小。可以從 這里 了解這個版本的信息。
我們在虛擬機上安裝 WooCommerce 并基于 Apache 2.4 默認的 prefork 和 mod_php 配置發送 1200 請求進行負載測試。
首先,我們在 https://tools.pingdom.com/ 網站對 libapache2-mod-php7 和 mpm_prefork_module 進行測試:
然后,我們對 MPM 的 evnet 模塊僅需測試。
這需要將 multiverse 加入到 /etc/apt/sources.list:
deb http://archive.ubuntu.com/ubuntu xenial main restricted universe multiverse deb http://archive.ubuntu.com/ubuntu xenial-updates main restricted universe multiverse deb http://security.ubuntu.com/ubuntu xenial-security main restricted universe multiverse deb http://archive.canonical.com/ubuntu xenial partner
隨后,執行 sudo apt-get update 來安裝 libapache2-mod-fastcgi 和 php-fpm。
sudo apt-get install libapache2-mod-fastcgi php7.0-fpm
由于 php-fpm 獨立于 Apache 服務器,所以需要重啟服務:
sudo service start php7.0-fpm
然后,關閉 prefork 模塊,啟用 event 模式和 proxy_fcgi:
sudo a2dismod php7.0 mpm_prefork sudo a2enmod mpm_event proxy_fcgi
將下面的代碼加入到 Apache 虛擬機:
SetHandler "proxy:fcgi://127.0.0.1:9000/"
端口號需要與 php-fpm 配置保持一致 /etc/php/7.0/fpm/pool.d/www.conf。可以從 這里 了解 PHP-FPM 配置。
現在,我們調整 mpm_evnet 配置選項 /etc/apache2/mods-available/mpm_event.conf,記住我們的 mini-VPS 資源在測試上受限 - 所以需要減少一些默認值。有關指令的詳細信息可以查看 指令文檔,關于 event 模塊的可以閱讀 這個章節。記住,重啟服務會消耗大量的內存資源。MaxRequestWorkers 指令設置最大請求數限制:將 MaxConnectionsPerChild 設置為非零非常重要,它可以防止內存泄露。
StartServers 1 MinSpareThreads 30 MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 30 MaxRequestWorkers 80 MaxConnectionsPerChild 80
使用 sudo service apache2 restart 重新啟動服務器,如果我們修改了如 ThreadLimit 這類指令,我們還需要顯示的停止和啟動服務 sudo service apache2 stop; sudo service apache2 start。
在 Pingdom 上的測試結果顯示頁面加載時間縮短了一半以上。
Apache 配置其它技巧禁用 .htaccess:.htaccess 允許在無需重啟服務時對根目錄下的每個目錄多帶帶進行配置。所以,服務器接收請求后會遍歷所有目錄,查找 .htaccess 文件,這會導致性能下降。
以下引用自 Apache 官方文檔:
通常,僅當你的主服務器配置文件沒有進行相應的訪問控制時才需要使用 .htaccess 文件。... 一般,需要盡可能避免使用 .htaccess 文件。當需要使用 .htaccess 文件時,都可以在主服務器配置的 directory 配置節點去執行配置
解決方案是到 /etc/apache2/apache2.conf 禁用重寫功能:
AllowOverride None
如果需要在特定目錄啟用重寫功能,可以到虛擬主機配置文件中指定節點啟用:
AllowOverride All
更多使用技巧:
使用 mod_expire 控制瀏覽器緩存 - 通過設值 expires 響應頭。
關閉 HostNameLookups 功能 - HostNameLookups 自 Apache 1.3 器默認關閉 off,由于它會導致性能下降,所以直接關閉就好。
Apache2buddy 是一個簡單的腳本,我們可以運行并獲得調整系統的提示:curl -sL https://raw.githubusercontent... | perl
NginxNginx 是一款 事件驅動(event-driven) 非阻塞模式的 Web 服務器。下面摘自 Hacker News:
與事件循環相比 fork 子進程消耗更多系統資源?;谑录?HTTP 服務器完勝。
這個言論引發了對 Hacker News 的吐槽,從我的經驗來看,從 Apache 的 mpm_prefork 切換到 Nginx 可以保證網站不宕機。簡單的將 Web 服務器切換到 Nginx 就可做到這點。
可以從 這里 獲取 Nginx 架構的全面分析。
配置 NginxNginx 推薦將 worker 進程數量設置為 PC 的 核心數(類似 Apache 的 mpm_event 配置),將 /etc/nginx/nginx.conf 配置文件中 worker_processes 指令設置為 auto (默認為 1)。
worker_connections 設置單個 worker 進程能夠處理的連接數。默認為 512,不過通??梢栽黾犹幚磉B接數量。
keepalive 連接數 一樣會影響服務器性能,在基準測試中一般看不到這個 請求頭。
從 Nginx 網站了解到:
HTTP keepalive 連接數是能夠有效減少延遲提升 web 頁面加載速度的優化性能手段。
創建新的 TCP 連接會 消耗資源 - 尤其是啟用安全的 HTTPS 加密協議。HTTP/2 協議通過 復用特性 可以減少資源消耗。復用已經創建好的連接能夠降低請求時間。
Apache 的 mpm_prefork 和 mpm_worker 對比 keepalive 事件循環在并發處理能力上存在不足。所以在 Apache 2.4 中引入 mpm_event 模塊對此進行了修復,然而對于 Nginx 事件驅動是唯一默認處理模式。Nginx 的 worker 進程可以同時處理數千個連接,如果使用它作為反向代理或負載均衡器的話,Nginx 還可以使用本地 keepalive 連接池,而無需使用 TCP 連接所帶來的開銷。
keepalive_requests 指令用于設置單個客戶端能夠在一個 keepalive 連接上處理的請求數量。
keepalive_timeout 設置空閑 keepalive 連接保持打開的時間。
keepalive 是關于 upstream(上游) 服務器和 Nginx 連接有關的配置 - 當 Nginx 充當代理或負載均衡服務器角色時。表示在空閑狀態 upstream 服務器在單個 worker 進程中支持的 keepalive 連接數。
當使用 upstream keepalive 連接處理請求時,需要將如下指令添加到 nginx 主配置文件中:
proxy_http_version 1.1; proxy_set_header Connection "";
nginx upstream 連接由 ngx_http_upstream_module 模塊管理。
如果我們的客戶端應用需要不斷輪詢服務端應用進行數據更新,可以通過 keepalive_requests 和 keepalive_timeout 增加連接數。同時 keepalive 指令值不應太大,這樣就能夠保證其他的 upstream 服務器也能夠處理其它請求。
這些配置需要基于不同的應用的測試結果來進行多帶帶配置。這或許就是 keepalive 沒有默認值的原因。
使用 UNIX 套接字默認情況下,nginx 使用多帶帶的 PHP 進程將 HTTP 請求轉發到 PHP 文件。這種場景就是代理(類似 Apache 需要設置 php7.0-fpm)。
我們所用的 Nginx 虛擬主機配置如下:
location ~ .php$ { fastcgi_param REQUEST_METHOD $request_method; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass 127.0.0.1:9000; }
由于 FastCGI 與 HTTP 是不同的協議,前兩行配置是將一些參數和請求頭轉發到 php-fpm 進程管理器,最后一行設置了請求的代理方式 - 通過本地網絡套接字完成。
這對于多服務器它很實用,因為 nginx 可以對遠程服務器進行代理轉發。
但是,如果我們將網站托管在一臺服務器上時,我們就應該使用 UNIX 套接字來監聽 php 進程:
fastcgi_pass unix:/var/run/php7.0-fpm.sock;
UNIX 套接字相比 TCP 連接有更好的 性能,從安全角度來講這個設置也是更優的選擇。你可以從 Rackspace 站點的 這篇文章 掌握更多配置細節。
這個技巧同樣適用于 Apache 服務器??梢缘?這里 進行學習。
gzip_static:在 web 服務器優對靜態文件進行壓縮處理是公認的行之有效的技術。這表示我們對大文件做出讓步,會對哪些超過指定大小的文件進行壓縮處理,因為這些文件在請求時消耗更多的資源。Nginx 提供一個 gzip_static 指令,允許我們使用服務器的 gzip 壓縮工具對文件進行壓縮 - 壓縮后的文件擴展名為 .gz 而非不同文件:
location /assets { gzip_static on; }
這樣 Nginx 服務器會長時間 style.css 壓縮成 style.css.gz 文件(此時我們需要自己處理解壓)。
通過這種方式,在 CPU 周期內無需在每個請求時動態的對文件進行壓縮處理。
啟用 Nginx 服務器緩存如果不涉及講解如何進行緩存配置,那么對 Nginx 講解就是不是完整的。由于 Nginx 緩存非常高效,以至于諸多系統管理員認為使用多帶帶的 HTTP 緩存 都是多余的(如 Varnish)。Nginx 緩存配置也十分簡單。
proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m;
這些指令配置在 server 塊級指令中。proxy_cache_path 參數可以是任何緩存保存的路徑。 levels 設置 Nginx 可以緩存什么層級目錄。出于性能考量,兩層目錄通常就可以了。因為目錄遞歸處理非常消耗資源。keys_zone 參數用于識別共享內存的緩存鍵名,10m 表示該鍵名能夠使用的內存大?。?0 MB 通常就夠了;這不是實際緩存內容的空間大?。?。可選的 max_size 指令設置緩存的內容上限 - 這里是 10GB。如果未設置該值,則會占用所有可用的存儲空間。inactive 指令設置數據未被命中時可被緩存的有效期。
設置完成后,將緩存鍵名添加到 server 或 location 指令塊就好了:
proxy_cache my_cache;
Nginx 容錯層能夠通知源服務器或 upstream 服務器在服務器出錯或關閉時從緩存中獲取命中的數據:
proxy_cache_use_stale error timeout http_500 http_502 http_503 http_504;
有關 server 和 location 指令對于緩存的配置細節可以閱讀 這里。
proxy_cache_* 用于靜態資源緩存,不過通常我們希望能夠緩存動態內容 - 如 CMS 或其他應用。此時,我們可以使用 fastcgi_cache_* 指令來代替 proxy_cache_*:
fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=my_cache:10m inactive=60m; fastcgi_cache_key "$scheme$request_method$host$request_uri"; fastcgi_cache_use_stale error timeout invalid_header http_500; fastcgi_ignore_headers Cache-Control Expires Set-Cookie; add_header NGINX_FASTCGI_CACHE $upstream_cache_status;
上面的最后一行會設置響應頭,來告知我們內容是否從緩存中獲取。
然后,在我們的 server 或 location 塊中,我們可以為緩存設置一些無需緩存的場景 - 例如,當請求 URL 中存在查詢字符串時:
if ($query_string != "") { set $skip_cache 1; }
另外,在 server 指令下的 .php 塊指令里,我們會添加如下內容:
try_files $uri =404; include fastcgi_params; fastcgi_read_timeout 360s; fastcgi_buffer_size 128k; fastcgi_buffers 4 256k; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/run/php/php7.0-fpm.sock; fastcgi_index index.php; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_cache my_cache; fastcgi_cache_valid 60m;
以上,fastcgi_cache* 和 fastcgi_no_cache 就配置完可緩存和不可緩存的所有規則。
你可以從 Nginx 官網 文檔 中獲取這些指令的指引。
要了解更多信息,Nginx 提供了相關主題的 會議,還有好多免費的 電子書。
總結我們試圖介紹一些有助于我們改進 Web 服務器性能的技術,以及這些技術背后的理論。但是這個主題才涉及皮毛:我們還沒有涵蓋 Apache 和 Nginx 或多服務器有關如何設置反向代理的講解。使用這兩種服務器實現最佳方式是依據測試和分析特定的案例來進行選擇。這是一個永無止境的話題。
Apache vs Nginx Performance: Optimization Techniques
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/40064.html
摘要:服務器市場份額。子進程負責創建由指令設置的服務器線程,同時還負責監聽接收到的請求,并將請求分發給處理線程。在版本引入了模塊,這個模塊基于模塊創建的,并加入了獨立的監聽線程來管理請求處理完成后的休眠的連接。基于事件的服務器完勝。 譯文首發于 Apache 與 Nginx 性能對比:Web 服務器優化技術,轉載請注明出處。 多年前 Apache 基金會 Web 服務器 簡稱「Apache」...
摘要:大型網站建議用自代的集群功能從個人過往的使用情況來看,的負載能力比高很多。最新的服務器也改用了。你對的需求決定你的選擇。在模式下,如果處理慢或者前端壓力很大的情況下,很容易出現進程數飆升,從而拒絕服務的現象。 1、nginx相對于apache的優點: 輕量級,同樣起web 服務,比apache占用更少的內存及資源 抗并發,nginx 處理請求是異步非阻塞的,而apache 則是阻塞型的...
摘要:大型網站建議用自代的集群功能從個人過往的使用情況來看,的負載能力比高很多。最新的服務器也改用了。你對的需求決定你的選擇。在模式下,如果處理慢或者前端壓力很大的情況下,很容易出現進程數飆升,從而拒絕服務的現象。 1、nginx相對于apache的優點: 輕量級,同樣起web 服務,比apache占用更少的內存及資源 抗并發,nginx 處理請求是異步非阻塞的,而apache 則是阻塞型的...
摘要:模式,單實例多進程,常用于多語言混編,比如等,不支持端口復用,需要自己做應用的端口分配和負載均衡的子進程業務代碼。就是我們需要一個調度者,保證所有后端服務器都將性能充分發揮,從而保持服務器集群的整體性能最優,這就是負載均衡。 showImg(https://segmentfault.com/img/remote/1460000019425391?w=1440&h=1080); Nod...
閱讀 3393·2021-09-22 15:01
閱讀 524·2019-08-30 11:11
閱讀 950·2019-08-29 16:17
閱讀 1209·2019-08-29 12:23
閱讀 2023·2019-08-26 11:48
閱讀 3176·2019-08-26 11:48
閱讀 1415·2019-08-26 10:33
閱讀 1927·2019-08-26 10:30