如何讓你的Nginx提升10倍效能?

轉自:ITPUB
提升Web應用的效能從未像今天這樣刻不容緩。
線上經濟活動的比例日益提高,就連發展中國家和地區的經濟活動都已經有5%以上線上進行了。在這個超級連結、隨時線上的現代世界,使用者的期望也遠非昔日可比。如果你的網站不能馬上響應,你的應用不能立即執行,使用者轉身就會投奔你的競爭對手。
亞馬遜十幾年前的一項研究表明,頁面載入時間減少1/10秒,能夠使其營收增長1%。另一項調查也顯示,一多半受訪站點所有者提到因為自己應用的效能不佳導致了收入減少或者使用者流失。
一個網站到底多快才行?頁面載入每花1秒鐘,就有大約4%的使用者走掉。排名最靠前的電商站點的首次互動時間為1至3秒,這個區間的轉換率最高。顯而易見,Web應用效能的重要性與日俱增。
提升效能其實不難,難的是怎麼看到結果。本文給出能夠提升大約10倍網站效能的10個建議供大家參考。如此全面地涵蓋各種效能最佳化技術,這還是頭一回,但這些建議可能需要NGINX的一點支援。除了效能,這些建議也會涉及提升安全性。
建議一:使用反向代理伺服器讓應用更快更安全
如果你的Web應用只跑在一臺機器上,那要提升其效能非常簡單:換一臺更快的,多配幾個處理器,多加幾條記憶體,磁碟陣列也要高速的。換了以後,這臺機器上跑的WordPress伺服器、Node.js或Java應用速度都會加快。(要是應用還會訪問另一臺資料庫伺服器,那也簡單:找兩臺更快的機器,用更快的網路連起來就行了)
麻煩在於,機器速度並不是問題。很多時候Web應用慢,是因為要在各種任務之間切換,一會兒要處理數千個連線上的使用者請求,一會兒要向磁碟讀寫檔案,一會兒又要執行應用的程式碼,一會兒又要去幹別的。應用伺服器因此可能出現各種狀況,耗盡記憶體、交換檔案,或者讓很多請求等待一個硬碟I/O之類的任務。
除了升級硬體,其實你還可以選擇另外一種完全不同的方法:加一臺反向代理伺服器,分擔上述一些任務。反向代理伺服器位於執行應用的機器之前,負責處理來自外網的請求。反向代理伺服器直接連到網際網路,它與應用伺服器通訊使用的是快速的內部網路。
反向代理伺服器可以讓應用伺服器專注於構建頁面,然後交給反向代理向外網傳送,而不必理會使用者與應用的互動。由於不必等待客戶端的響應,應用伺服器的執行速度能達到接近最優的水平。
增加反向代理伺服器同時也可以為Web伺服器增添靈活性。比如,假設執行某種任務的伺服器過載了,那隨時可以再增加一臺同類伺服器;而如果這臺伺服器掛了,替換它也很容易。
鑑於這種靈活性,反向代理伺服器往往也是其他效能最佳化手段的先決條件,比如:
  • 負載均衡(參見“建議二”),反向代理伺服器上執行負載均衡服務,把流量平均分配給幾臺應用伺服器。有了負載均衡,新增應用伺服器根本不需要修改應用。
  • 快取靜態檔案(參見“建議三”),圖片或程式碼之類的可以直接請求的檔案,都可以儲存在反向代理伺服器中,以便直接發給客戶端。這樣不僅可以更快地響應請求,還能減輕應用伺服器的負擔,加快其執行速度。
  • 保證站點安全,可以配置反向代理伺服器提升其安全級別,透過它監控來快速識別和響應攻擊,從而儲存應用伺服器安全。
NGINX專門為使用反向代理伺服器做了設計,使其天然支援上述最佳化。由於使用事件驅動的處理機制,NGINX比傳統伺服器效率更高。NGINX Plus則增加了更高階的反向代理功能,如應用體檢、特有的請求路由、高階快取和售後支援。

傳統伺服器與NGINX Worker的比較

建議二:增加負載均衡伺服器
增加負載均衡伺服器相對簡單,但卻能顯著提升站點效能和安全性。透過它把流量分配給多個伺服器,就可以不必升級Web伺服器了。就算應用本身寫得不太好,或者難以擴充套件,負載均衡都可以在不做其他改變的情況下提升使用者體驗。
負載均衡伺服器首先是一個反向代理伺服器(參見“建議一”),負責把來自網際網路的請求轉發給其他伺服器。這裡關鍵在於負載均衡伺服器可以支援兩臺以上的應用伺服器,使用一種選擇演算法在不同的伺服器間分配請求。最簡單的負載均衡演算法是迴圈排程,即把新請求依次轉發給可用伺服器中的下一臺伺服器。其他演算法還有把請求發給活動連線最少的伺服器。NGINX Plus支援一種功能,就是把使用者會話保持在同一臺伺服器上,叫做會話保持。
負載均衡伺服器可以避免一臺伺服器過載而其他伺服器過閒,從而極大提升效能。同時,有了它還可以讓Web伺服器擴容更簡單,因為可以選用比較便宜的伺服器,同時保證物盡其用。
可以透過負載均衡排程的協議包括HTTP、HTTPS、SPDY、HTTP/2、WebSocket、FastCGI、SCGI、uwsgi、memcached,以及其他一些應用形式,包括基於TCP的應用和其他第四層的協議。為此,首先要分析Web應用,看效能短板在哪裡,然後再確定使用哪一個。
同一臺伺服器或用於負載均衡的伺服器也可以承擔其他任務,比如SSL終止、視客戶端不同支援HTTP/1/x或HTTP/2、快取靜態檔案。
NGINX經常被用來做負載均衡,更多資訊請參考我們以前發的介紹性文章、有關配置的文章、電子書和相關的線上影片,當然還有文件。我們的商業版本NGINX Plus支援更多的負載均衡功能,如基於伺服器響應時間路由負載和支援微軟NTLM協議的負載均衡。
建議三:快取靜態及動態內容
快取能提升Web應用效能,因為可以更快地把內容交付給客戶端。快取的策略包括預處理內容、在較快的裝置上儲存內容、把內容儲存在靠近客戶端的地方,以及同時運用這些策略。
快取有兩種。
  • 靜態內容快取,不常變化的檔案,如圖片(JPEG、PNG)和程式碼(CSS、JavaScript),可以儲存在邊緣伺服器中,以便快速從內容或磁碟中獲取。
  • 動態內容快取,很多Web應用會為每個頁面請求生成全新的HTML,把生成的每個HTML都快取一小段時間,可能顯著減少需要生成的頁面總數,同時又可以保證交付的內容足夠新鮮。
假設一個頁面每秒被檢視10次,而你快取它1秒,那麼90%針對這個頁面的請求都將來自在快取。如果你單獨快取靜態內容,那麼即使全新生成的頁面,很可能大部分都來自快取的內容。
快取Web應用生成內容的技術主要分三種。
  • 把內容放到離使用者近的地方。離使用者近,傳輸時間少。
  • 把內容放到較快的機器上。機器快,檢索速度快。
  • 把內容從過度使用的機器中拿走。有時候機器會比在專注執行特定任務時慢很多,那是因為太多工讓它們分心。這時候把內容拿到其他機器上,不僅對快取的內容有好處,對非快取的內容同樣有利,因為託管它們的主機的負擔減輕了。
Web應用的快取可以在Web應用伺服器內部或外部實現。首先,考慮快取動態內容,以減輕應用伺服器的負載。其次,快取用於靜態內容(包括那些動態生成內容的臨時副本),進一步減輕應用伺服器的負擔。然後,考慮把快取轉移到其他更快或更靠近使用者的機器,給應用伺服器減負,縮短傳輸時間。
用好快取能顯著加快應用的響應速度。對很多網頁來說,大圖片之類的靜態資料,往往佔據一半以上的內容。不用快取,查詢和傳輸這類資料可能會花好幾秒鐘,而用快取,則可能只要花幾分之一秒。
可以舉一個例子來說明怎麼使用快取,NGINX和NGINX Plus透過兩個指令來設定快取:proxy_cache_path和proxy_cache指定快取的位置和大小、最長快取時間以及其他引數。使用第三個(也是很受歡迎的)指令proxy_cache_use_stale,甚至可以告訴快取在本來應該提供新鮮內容的伺服器太忙或宕機時,提供原來的舊檔案,對客戶端來說,拿到內容總比拿不到強。從使用者角度看,這樣也可以樹立你的站點或應用非常穩定的形象。
NGINX Plus支援高階快取功能,包括快取淨化(caching purging)和透過控制板以視覺化的形式展示快取狀態,實現即時監控。
要了解NGINX中關於快取的更多資訊,可以看看參考文件和NGINX Plus Admin Guide中的NGINX Content Caching。
注意: 快取涉及開發、決策和運維,完善的快取策略,比如本文提到的這些,能夠體現從DevOps角度考慮的價值。也說是說,開發人員、架構師、運維人員此時攜手,共同保障一個網站的功能、響應時間、安全和業務目標。
建議四:壓縮資料
壓縮同樣能極大提升效能。圖片、影片、音樂等檔案都有非常成熟和高效的壓縮標準(JPEG和PNG、MPEG-4、MP3),任何一個標準都可以把檔案大小縮小一個數量級甚至更多。
文字檔案,包括HTML(純文字和HTML標籤)、CSS和JavaScript程式碼,經常在不壓縮的情況下傳輸。壓縮這些資料對提升Web應用的感知效能有時候特別明顯,尤其是移動使用者的網路很慢又不穩定的情況下。
因為文字資料透過對於頁面互動能夠起到必要的支援作用,而多媒體資料則更多是錦上添花的作用。聰明的內容壓縮可以把HTML、JavaScript、CSS等文字內容的縮小30%以上,因此能夠相應地減少載入時間。
如果你使用SSL,壓縮又可以減少必須經過SSL編碼的資料量,從而補償了壓縮這些資料的CPU時間。
壓縮資料的方法非常多。比如,建議六中關於HTTP/2的部分就描述了一個新穎的壓縮思路,特別適合首部資料壓縮。還有一個關於文字壓縮的例子,就是可以在NGINX中開啟GZIP壓縮。預壓縮文字資料之後,可以使用gzip_static指令直接傳送.gz檔案。
建議五:最佳化SSL/TLS
越來越多的網站在使用Secure Sockets Layer(SSL)及後來的Transport Layer Security(TLS)協議。SSL/TLS透過加密從源伺服器傳送給使用者的資料來提升網站安全性。Google會提升使用SSL/TLS的網站的搜尋引擎排名,將有力地推動這一程序。
儘管採用率越來越高,但SSL/TLS造成的效能損失也困擾著很多網站。SSL/TLS拖慢網站的原因有兩個。
1、每次開啟新連線的初次握手都必須建立加密金鑰,而瀏覽器使用HTTP/1.x對每個2、伺服器建立多個連線的方式進一步加劇了這個問題。
伺服器端加密資料和客戶端解密資料的操作同樣也是開銷。
為了鼓勵人們使用SSL/TLS,HTTP/2和SPDY(參見建議六)的作者將這兩個協議設計為只讓瀏覽器針對一次會話建立一個連線。這樣就把SSL導致效能降低的兩個主要原因之一消滅掉了。然而,說到最佳化SSL/TLS效能,還是有很多事情可做。
最佳化SSL/TLS的方法因Web伺服器而異。以NGINX為例,NGINX使用OpenSSL,運行於普通機器上,能夠提供接近定製機器的效能。NGINX SSL performance詳細介紹瞭如何將SSL/TLS加密和解密的開銷降至最低。
此外,這裡還有一篇文章,介紹了很多種提升SSL/TLS效能的方法。簡單總結一下,涉及的技術主要有如下幾種。
  • 會話快取。使用ssl_session_cache指令開啟快取,快取每次SSL/STL連線時用到的引數。
  • 會話票或ID。把特定SSL/TLS會話的資訊儲存為一個會話票或ID,以便連線重用,而不必重新握手。
  • OCSP封套。透過快取SSL/TLS證書資訊減少握手時間。
NGINX和NGINX Plus都可以來終止SSL/TLS,即處理客戶端資訊的加密和解密,同時與其他伺服器保持明文通訊。在NGINX或NGINX Plus中設定處理SSL/TLS終止可以採取這幾個步驟。而對於在接受TCP連線的伺服器上使用NGINX Plus而言,可以參考這裡的設定步驟。
建議六:實現HTTP/2或SPDY
已經使用SSL/TLS的站點,如果再使用HTTP/2或SPDY則很可能提升效能,因為一個連線只要一次握手。尚未使用SSL/TLS、HTTP/2和SPDY的站點切換到SSL/TLS(通常會降低效能),從響應速度方面看,可能是一次倒退。
谷歌2012年開始SPDY專案,致力於在HTTP/1.x之上實現更快的速度。HTTP/2則是IETF最近批准的基於SPDY的標準。SPDY得到了廣泛支援,但很快就將被HTTP/2取代。
SPDY和HTTP/2的關鍵在於只用一個連線,而非多個連線。這一個連線是多路複用的,因此可以同時承載多個請求和響應。
只維持一個連線,可以省掉多個連線所需的設定和管理消耗。而且一個連線對SSL特別重要,因為可以將SSL/TLS建立安全連線所需的握手時間降至最少。
SPDY協議要求使用SSL/TLS,HTTP/2並沒有正式要求,但目前所有支援HTTP/2的瀏覽器都只會在啟用SSL/TLS的情況下才會使用它。換句話說,支援HTTP/2的瀏覽器只有在網站使用SSL且伺服器接受HTTP/2流量的情況下才會使用HTTP/2。否則,瀏覽器會基於HTTP/1.x通訊。
實現了SPDY或HTTP/2之後,域名分片、資源合併、圖片精靈等之前針對HTTP的效能最佳化措施就用不著了。因此也可以簡化程式碼和部署。關於HTTP/2會帶來哪些變化,可以參考我們的這個白皮書。

NGINX很早就開始支援SPDY,而且今天使用SPDY的大多數站點都在執行NGIN
X。NGINX同樣率先支援了HTTP/2,2015年9月,NGINX開源和NGINX Plus開始支援 HTTP/2。
隨著時間推移,NGINX希望大多數站點啟用SSL並遷移到HTTP/2。這樣不僅可以讓網站更安全,而且隨著新的最佳化技術不斷湧現,也可以透過簡單的程式碼實現更高的效能。
建議七:升級軟體
提升應用效能的一個簡單的方法,就是根據可靠性及效能選擇軟體。此外,高質量元件的開發者更可能不斷提升效能和修復問題,因此使用最新的穩定版本是划算。新發布的版本會得到開發者和使用者更多的關注,同時也會利用新的編譯器最佳化技術,包括針對新硬體的調優。
相對舊版本,新發布的穩定版本明顯效能更高。堅持升級,也可以保證在調優、問題修復和安全警報方面與時俱進。
不升級軟體也會妨礙利用新能力。從2016年下半年開始,HTTP/2會要求OpenSSL 1.0.2,該版本釋出於2015年1月。
NGINX使用者可以從NGINX開源軟體的最新版本或NGINX Plus開始,它們支援套接字共享、執行緒池(參見下文),而且都會持續最佳化效能。因此,檢查一下自己的軟體,儘量把它們升級到最新的版本。
建議八:調優Linux
Linux是今天大多數Web伺服器的底層作業系統,作為一切基礎設施的基礎,Linux對提升效能至關重要。預設情況下,很多Linux系統都比較保守,僅以桌面辦公為需求,以佔用少量資源為調優目標。對於Web應用而言,為達到效能最佳,肯定需要重新調優。
Linux最佳化因Web伺服器而異。以NGINX為例,可以從以下幾方面考慮。
存量佇列。如果發現有一些連線得不到處理,可以增大net.core.somaxconn,即等待NGINX處理的最大連線數。如果這個連線數限制過小,應該可以看到錯誤訊息,可以逐步提高這個值,直到錯誤訊息不再出現。
  • 檔案描述符。NGINX對每個連線最多使用兩個檔案描述符。如果系統服務於很多連線,可能需要增大sys.fs.file_max這個對描述符的系統級限制,以及nofile這個使用者檔案描述符限制,以支援增大後的負載。
  • 臨時埠。在作為代理使用時,NGINX會為每個上游伺服器建立臨時埠。可以設定net.ipv4.ip_local_port_range,增大埠值的範圍,以增加可用的埠量。此外,還可以減小net.ipv4.tcp_fin_timeout的值,它控制非活動埠釋放重用的等待時間,加快週轉。
  • 對NGINX而言,請參考NGINX效能調優指南,瞭解如何不費吹灰之力將你的Linux系統最佳化為能夠支援更大的吞吐量。
建議九:調優Web伺服器
無論使用什麼Web伺服器,都需要針對應用對其調優。以下建議適用於任何Web伺服器,但會給出只有NGINX的設定說明。
  • 訪問日誌。不要每個請求的日誌都馬上寫到磁碟,可以在記憶體裡做個快取,然後批次定入。對NGINX而言,將buffer=_size_引數新增到access_log指令,等記憶體緩衝區寫滿後再把日誌寫到磁碟。如果你添加了**flush=_time_**引數,那麼緩衝區的內容也會按照指定時間寫入磁碟。
  • 緩衝。緩衝用於在記憶體裡儲存部分響應,直到緩衝區被填滿,可以實現對客戶端更有效的響應。無法寫入記憶體的響應會被寫到磁碟,從而降低效能。在NGINX的緩衝啟用時,可以使用proxy_buffer_size和proxy_buffers指令來管理它。
  • 客戶端活動連線。活動連線可以減少時間消耗,特別是在使用SSL/TLS的情下。對NGINX而言,可以針對客戶端提高keepalive_requests的數值,預設值為100;也可以增大keepalive_timeout的值,讓活動連線持續時間更長,從而讓後續請求得到更快響應。
  • 上游活動連線。上游連線,即連線到應用伺服器、資料庫伺服器的連線,同樣可以從活動連線的設定中獲得好處。對上游連線來說,可以增加活動連線,也就是每個工作程序可用的空閒活動連線的數量。這樣可以增進連線重用,減少重開連線。關於活動連線的更多資訊,請參考這篇部落格。
  • 限制。限制客戶端使用的資源可以提升效能和安全性。對NGINX而言,limit_conn和limit_conn_zone指令限制指定源的連線數,而limit_rate限制頻寬。這些設定可以防止合法使用者“侵吞”資源,同時也有助於防止攻擊。limit_req和limit_req_zone指令限制客戶端請求。對於到上游伺服器的連線,可以在上游配置區的伺服器指令中使用max_conns引數,它限制對上游伺服器的連線,防止過載。相關的佇列指令會建立一個佇列,在max_conns限制到達後將指定的請求數儲存指定的時間。
  • 工作程序。工作程序負責處理請求。NGINX採用基於事件的模型和OS相關的機制有效地在工作程序間分配請求。建議將worker_processes的值設定為每個CPU一個工作程序。如果需要,大多數系統都支援提高worker_connections的值(預設為512)。可以透過試驗找到最適合你係統的這個值。
  • 套接字分片。通常,一個套接字監聽器向所有工作程序分發新連線。套按字分片則為每個工作程序都建立一個套接字監聽器,由核心在套接字監聽器可用時為其指定連線。這樣可以減少鎖爭用,提升多核系統上的效能。要啟用套接字分片,在listen指令中包含reuseport引數。
  • 執行緒池。一個費時的操作會阻塞任何計算機程序。對Web伺服器軟體來說,磁碟訪問可能阻礙很多較快的操作,比如記憶體中的計算和複製。在使用執行緒池的情況下,慢操作會被指定給一組獨立的任務,而主處理迴圈會繼續執行較快的操作。磁碟操作完成後,結果會返回到主處理迴圈。在NGINX中,read()系統呼叫和sendfile()被轉載到了執行緒池。

提示 修改任何作業系統及周邊裝置的設定時,每次只修改一項,然後測試效能。如果該項修改導致了問題,或者並未提升效能,再改回去。
建議十:監控即時動態以發現問題和瓶頸
儲存應用高效能的關鍵是即時監控應用效能。必須即時監控特定裝置及相應Web基礎設施中應用的動態。
監控站點活動多數情況下是被動的,它只告訴你發生了什麼,至於如何發現和解決問題,則是你自己的事情。
監控可以捕獲以下幾種問題:
1、伺服器停機
2、伺服器不穩,漏處理連線
3、伺服器出現大面積快取失效
4、伺服器傳送的內容不對
New Relic或Dynatrace等全域性性的效能監控工具,可以幫我們監控遠端載入頁面的時間,而NGINX則可以幫你監控應用交付這一端。應用的效能資料可以告訴你最佳化手段什麼時候真正給使用者帶去了不同的體驗,以及什麼時候需要擴容以滿足越來越多的流量。
為了幫助使用者儘快發現問題,NGINX Plus增加了應用程式體檢功能,會報告經常重複出現的問題。NGINX Plus還具備session draining特性,會在已有任務完成前阻止新連線,以及慢啟動容量,從而讓恢復的伺服器在負載均衡叢集中達到應有的速度。使用得當的情況下,健康體檢會在問題顯著影響使用者體驗之前幫你定位問題,而session draining和慢啟動則讓你替換伺服器時不影響感知的效能和線上時間。這張圖展示了NGINX Plus內建的即時活動監控的控制板,涵蓋了伺服器、TCP連線和快取。

結論:10倍效能提升
能提升因Web應用不同會有巨大差異。實際的提升取決於預算、時間,以及現有實現的與理想效能的差距。那麼怎麼讓你的應用獲得10倍的效能提升呢?
為了幫大家理解每項最佳化建議的潛能,下面再針對之前的建議給出一些實施方針,希望大家各取所需。
  • 反向代理伺服器及負載均衡。沒有負載均衡或池負載均衡,可能導致極低的效能。新增一個反向代理伺服器,比如NGINX,可以減少Web應用在記憶體和磁碟之間的往返。負載均衡可以把任務從過載的伺服器轉移到空閒的伺服器,也便於擴充套件。這些改變能極大地提升效能,與原有的部署方式最差的時候相比,10倍效能提升是很輕鬆的事,即使不到10倍那也在總體上有了質的飛躍。
  • 快取動態和靜態內容。如果你的Web伺服器同時又充當了應用伺服器,那麼透過快取動態內容就可以達到高峰期10倍的效能提升。快取靜態內容也可以有幾倍的效能提升。
  • 壓縮資料。使用JPEG、PNG、MPEG-4以及MP3等壓縮格式能顯著提升效能。如果這些手段都用上了,那麼壓縮的文字資料(程式碼及HTML)可以將初始頁面載入時間提升兩倍。
  • 最佳化SSL/TLS。安全握手對效能有很大影響,因此對其進行最佳化可以讓初次響應加快兩倍,對於文字內容較多的網站尤其如此。最佳化SSL/TLS下的媒體檔案帶來的效能提升很小。
  • 實施HTTP/2和SPDY。在使用SSL/TLS的情況下,這兩個協議有可能提升網站的整體效能。
  • 調優Linux和Web伺服器。使用最佳化的緩衝策略、使用活動連線,將耗時的任務轉載至獨立的執行緒池,可以顯著提升效能。比如執行緒池可以將磁碟操作密集性任務的效能提升至少一個數量級。
譯者:為之漫筆
來源:www.zcfy.cc/article/10-tips-for-10x-application-performance-nginx-22.html
原文:https://www.nginx.com/blog/10-tips-for-10x-application-performance/
END
官方站點:www.linuxprobe.com
Linux命令大全:www.linuxcool.com
劉遄老師QQ:5604215
Linux技術交流群:2636170
(新群,火熱加群中……)
想要學習Linux系統的讀者可以點選"閱讀原文"按鈕來了解書籍《Linux就該這麼學》,同時也非常適合專業的運維人員閱讀,成為輔助您工作的高價值工具書!


相關文章