建議收藏!可提高系統 10 倍性能的 10 個建議!

101509087893.png
譯者:爲之漫筆
來源:http://www.zcfy.cc/article/10...
原文:https://www.nginx.com/blog/10...html

一個網站到底多快才行?頁面加載每花1秒鐘,就有大約4%的用戶走掉。排名最靠前的電商站點的首次交互時間爲1至3秒,這個區間的轉換率最高。顯而易見,Web應用性能的重要性與日俱增。nginx

提高性能其實不難,難的是怎麼看到結果。本文給出可以提高大約10倍網站性能的10個建議供你們參考。如此全面地涵蓋各類性能優化技術,這仍是頭一回,但這些建議可能須要NGINX的一點支持。除了性能,這些建議也會涉及提高安全性。web

建議一:使用反向代理服務器讓應用更快更安全算法

果你的Web應用只跑在一臺機器上,那要提高其性能很是簡單:換一臺更快的,多配幾個處理器,多加幾條內存,磁盤陣列也要高速的。換了之後,這臺機器上跑的WordPress服務器、Node.js或Java應用速度都會加快。(要是應用還會訪問另外一臺數據庫服務器,那也簡單:找兩臺更快的機器,用更快的網絡連起來就好了。)數據庫

麻煩在於,機器速度並非問題。不少時候Web應用慢,是由於要在各類任務之間切換,一下子要處理數千個鏈接上的用戶請求,一下子要向磁盤讀寫文件,一下子又要運行應用的代碼,一下子又要去幹別的。應用服務器所以可能出現各類情況,耗盡內存、交換文件,或者讓不少請求等待一個硬盤I/O之類的任務。瀏覽器

緩存

除了升級硬件,其實你還能夠選擇另一種徹底不一樣的方法:加一臺反向代理服務器,分擔上述一些任務。反向代理服務器位於運行應用的機器以前,負責處理來自外網的請求。反向代理服務器直接連到互聯網,它與應用服務器通訊使用的是快速的內部網絡。安全

反向代理服務器可讓應用服務器專一於構建頁面,而後交給反向代理向外網發送,而沒必要理會用戶與應用的交互。因爲沒必要等待客戶端的響應,應用服務器的運行速度能達到接近最優的水平。性能優化

增長反向代理服務器同時也能夠爲Web服務器增添靈活性。好比,假設執行某種任務的服務器過載了,那隨時能夠再增長一臺同類服務器;而若是這臺服務器掛了,替換它也很容易。服務器

鑑於這種靈活性,反向代理服務器每每也是其餘性能優化手段的先決條件,好比:

  • 負載均衡(參見「建議二」),反向代理服務器上運行負載均衡服務,把流量平均分配給幾臺應用服務器。有了負載均衡,添加應用服務器根本不須要修改應用。
  • 緩存靜態文件(參見「建議三」),圖片或代碼之類的能夠直接請求的文件,均可以保存在反向代理服務器中,以便直接發給客戶端。這樣不只能夠更快地響應請求,還能減輕應用服務器的負擔,加快其運行速度。
  • 保證站點安全,能夠配置反向代理服務器提高其安全級別,經過它監控來快速識別和響應攻擊,從而保存應用服務器安全。

NGINX專門爲使用反向代理服務器作了設計,使其自然支持上述優化。因爲使用事件驅動的處理機制,NGINX比傳統服務器效率更高。NGINX Plus則增長了更高端的反向代理功能,如應用體檢、特有的請求路由、高級緩存和售後支持。


傳統服務器與NGINX Worker的比較

建議二:增長負載均衡服務器

加負載均衡服務器相對簡單,但卻能顯著提高站點性能和安全性。經過它把流量分配給多個服務器,就能夠沒必要升級Web服務器了。就算應用自己寫得不太好,或者難以擴展,負載均衡均可以在不作其餘改變的狀況下提高用戶體驗。

負載均衡服務器首先是一個反向代理服務器(參見「建議一」),負責把來自互聯網的請求轉發給其餘服務器。這裏關鍵在於負載均衡服務器能夠支持兩臺以上的應用服務器,使用一種選擇算法在不一樣的服務器間分配請求。最簡單的負載均衡算法是循環調度,即把新請求依次轉發給可用服務器中的下一臺服務器。其餘算法還有把請求發給活動鏈接最少的服務器。NGINX Plus支持一種功能,就是把用戶會話保持在同一臺服務器上,叫作會話保持。

負載均衡服務器能夠避免一臺服務器過載而其餘服務器過閒,從而極大提高性能。同時,有了它還可讓Web服務器擴容更簡單,由於能夠選用比較便宜的服務器,同時保證物盡其用。

能夠經過負載均衡調度的協議包括HTTP、HTTPS、SPDY、HTTP/二、WebSocket、FastCGI、SCGI、uwsgi、memcached,以及其餘一些應用形式,包括基於TCP的應用和其餘第四層的協議。爲此,首先要分析Web應用,看性能短板在哪裏,而後再肯定使用哪個。

同一臺服務器或用於負載均衡的服務器也能夠承擔其餘任務,好比SSL終止、視客戶端不一樣支持HTTP/1/x或HTTP/二、緩存靜態文件。

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-四、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拖慢網站的緣由有兩個。

一、每次打開新鏈接的初次握手都必須建立加密密鑰,而瀏覽器使用HTTP/1.x對每一個二、服務器創建多個鏈接的方式進一步加重了這個問題。

服務器端加密數據和客戶端解密數據的操做一樣也是開銷。

爲了鼓勵人們使用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(一般會下降性能),從響應速度方面看,多是一次倒退。點擊這裏瞭解HTTP/2詳解。

谷歌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。這樣不只可讓網站更安全,並且隨着新的優化技術不斷涌現,也能夠經過簡單的代碼實現更高的性能。

建議七:升級軟件

升應用性能的一個簡單的方法,就是根據可靠性及性能選擇軟件。此外,高質量組件的開發者更可能不斷提高性能和修復問題,所以使用最新的穩定版本是划算。新發布的版本會獲得開發者和用戶更多的關注,同時也會利用新的編譯器優化技術,包括針對新硬件的調優。

相對舊版本,新發布的穩定版本明顯性能更高。堅持升級,也能夠保證在調優、問題修復和安全警報方面與時俱進。

不升級軟件也會妨礙利用新能力。好比,HTTP/2目前要求OpenSSL 1.0.1。從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基礎設施中應用的動態。

監控站點活動多數狀況下是被動的,它只告訴你發生了什麼,至於如何發現和解決問題,則是你本身的事情。

監控能夠捕獲如下幾種問題:

一、服務器停機

二、服務器不穩,漏處理鏈接

三、服務器出現大面積緩存失效

四、服務器發送的內容不對

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服務器。使用優化的緩衝策略、使用活動鏈接,將耗時的任務轉載至獨立的線程池,能夠顯著提高性能。好比線程池能夠將磁盤操做密集性任務的性能提高至少一個數量級。

但願你們本身多嘗試以上技術,也但願你們分享本身在性能改進方面的心得。

640.png