首頁 運維 Nginx 如何為高負載網路最佳化Nginx和Node.js

如何為高負載網路最佳化Nginx和Node.js

May 13, 2023 pm 01:31 PM
node.js nginx

網路調優
如果不先對nginx和node.js的底層傳輸機制有所了解,並進行針對性優化,可能對兩者再細緻的調優也會徒勞無功。一般情況下,nginx透過tcp socket來連接客戶端與上游應用程式。
我們的系統對tcp有許多閘限值與限制,透過核心參數來設定。這些參數的預設值往往是為一般的用途而定的,並不能滿足web伺服器所需的高流量、短生命的要求。
這裡列出了調優tcp可供候選的一些參數。要使它們生效,可以將它們放在/etc/sysctl.conf檔案裡,或者放入一個新設定文件,例如/etc/sysctl.d/99-tuning.conf,然後運行sysctl -p,讓核心裝載它們。我們是用sysctl-cookbook來幹這個體力活。
要注意的是,這裡列出來的值是可以安全使用的,但還是建議大家研究一下每個參數的意義,以便根據自己的負荷、硬體和使用情況選擇一個更合適的值。

複製程式碼 程式碼如下:

net.ipv4. ip_local_port_range='1024 65000'
net.ipv4.tcp_tw_reuse='1'
net.ipv4.tcp_fin_timeout='15'
net.core.netdev_max_backlog='4096'
net. ='16777216'
net.core.somaxconn='4096'
net.core.wmem_max='16777216'
net.ipv4.tcp_max_syn_backlog='20480'
net。 400000'
net.ipv4.tcp_no_metrics_save='1'
net.ipv4.tcp_rmem='4096 87380 16777216'
net.ipv4.tcp_syn_retries=v#yn'. 2'
net.ipv4.tcp_wmem='4096 65536 16777216'
vm.min_free_kbytes='65536'


1其中幾個重要的。

net.ipv4.ip_local_port_range
為了替上游的應用程式服務下游的客戶端,nginx必須開啟兩條tcp連接,一條連接客戶端,一條連接應用程式。當伺服器收到很多連線時,系統的可用連接埠將很快被耗盡。透過修改net.ipv4.ip_local_port_range參數,可以將可用連接埠的範圍改大。如果在/var/log/syslog 中發現有這樣的錯誤: “possible syn flooding on port 80. sending cookies”,即表示系統找不到可用連接埠。增大net.ipv4.ip_local_port_range參數可以減少這個錯誤。
net.ipv4.tcp_tw_reuse
當伺服器需要在大量tcp連線之間切換時,會產生大量處於time_wait狀態的連線。 time_wait表示連線本身是關閉的,但資源尚未釋放。將net_ipv4_tcp_tw_reuse設定為1是讓核心在安全時盡量回收連接,這比重新建立新連接便宜得多。
net.ipv4.tcp_fin_timeout這是處於time_wait狀態的連線在回收前必須等待的最小時間。改小它可以加快回收。
如何檢查連線狀態

使用netstat:
netstat -tan | awk '{print $6}' | sort | uniq -c
或使用ss:
ss - s
nginx
ss -s
total: 388 (kernel 541)
tcp: 47461 (estab 311, closed 47135, orphaned 4, synrecv 0, timewait 47135, orphaned 4, synrecv 0, timewait 47135/0phaned 4, synrecv 0, timewait 47135/03, 38#3), 38 #transport total ip ipv6
* 541 - -
raw 0 0 0
udp 13 10 3
tcp 326 325 1
inet 339 335 4
frag 0 0 0
隨著web伺服器的負載逐漸升高,我們就會開始遭遇nginx的某些奇怪限制。連接被丟棄,內核不停報syn flood。而這時,平均負載和cpu使用率都很小,伺服器明明是可以處理更多連線的狀態,真是令人沮喪。
經過調查,發現有非常多處於time_wait狀態的連線。這是其中一個伺服器的輸出:
有47135個time_wait連線!而且,從ss可以看出,它們都是已經關閉的連線。這說明,伺服器已經消耗了絕大部分可用端口,同時也暗示我們,伺服器是為每個連接都分配了新端口。調優網路對這個問題有一點幫助,但是連接埠仍然不夠用。
經過繼續研究,我找到了一個關於上行連接keepalive指令的文檔,它寫道:
設置通往上游伺服器的最大空閒保活連接數,這些連接會被保留在工作進程的快取中。
有趣。理論上,這個設定是透過在快取的連線上傳遞請求來盡可能減少連線的浪費。文件中也提到,我們應該把proxy_http_version設為"1.1",並清除"connection"頭部。經過進一步的研究,我發現這是一個很好的想法,因為http/1.1相比http1.0,大大優化了 tcp連接的使用率,而nginx預設用的是http/1.0。
按文件的建議修改後,我們的上行設定檔變成這樣:

複製程式碼 程式碼如下:###

upstream backend_nodejs {
server nodejs-3:5016 max_fails=0 fail_timeout=10s;
server nodejs-4:5016 max_fails=0 fail_timeout=10s;
server nodejs-5:5016 max_fails=0 max_fails=0 max_fails fail_timeout=10s;
server nodejs-6:5016 max_fails=0 fail_timeout=10s;
keepalive 512;
}

我還按它的建議修改了server一節的proxy設定。同時,增加了一個 p roxy_next_upstream來跳過故障的伺服器,調整了客​​戶端的 keepalive_timeout,並關閉存取日誌。設定變成這樣:

複製程式碼 程式碼如下:

server {
listen 80;
server_name fast.gosquared.com;
client_max_body_size 16m;
keepalive_timeout 10;
location / {
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_set_header connection "";
proxy_http_version 1.1;
access_log off;
error_log /dev/null crit;
}

採用新的設定後,我發現伺服器們佔用的socket 降低了90%。現在可以用少得多的連線來傳輸請求了。新的輸出如下:

ss -s

total: 558 (kernel 604)
tcp: 4675 (estab 485, closed 4183, orphaned 0, synrecv 0, timewait 4183/0), ports 0, timewait 4183/0), ports 2768# #transport total ip ipv6
* 604 - -
raw 0 0 0
udp 13 10 3
tcp 492 491 1
inet 505 501 4
node.js









得歸功於事件驅動式設計可以非同步處理i/o,node.js開箱即可處理大量的連線和請求。雖然有其它一些調優手段,但這篇文章將主要關注node.js的進程方面。
node是單執行緒的,不會自動使用多核心。也就是說,應用程式不能自動獲得伺服器的全部能力。
如何為高負載網路最佳化Nginx和Node.js實作node程序的叢集化

我們可以修改應用,讓它fork多個線程,在同一個連接埠上接收數據,從而實現負載的跨越多核心。 node有一個cluster模組,提供了實現這個目標所必需的所有工具,但要將它們加入應用中還需要很多體力活。如果你用的是express,ebay有一個叫cluster2的模組可以用。

防止上下文切換

當執行多個進程時,應該確保每個cpu核同一時間只忙於一個進程。一般來說,如果cpu有n個核,我們應該產生n-1個應用程式。這樣可以確保每個行程都能得到合理的時間片,而剩下的一個核留給核心調度程序來執行其它任務。我們還要確保伺服器上基本上不執行除node.js外的其它任務,防止出現cpu 的爭用。

我們曾經犯過一個錯誤,在伺服器上部署了兩個node.js應用,然後每個應用程式都開了n-1個進程。結果,它們互相之間搶奪cpu,導致系統的負荷急升。雖然我們的伺服器都是8核心的機器,但仍然可以明顯地感覺到由上下文切換引起的效能開銷。上下文切換是指cpu為了執行其它任務而掛起當前任務的現象。在切換時,核心必須掛起目前進程的所有狀態,然後裝載和執行另一個進程。為了解決這個問題,我們減少了每個應用程式開啟的進程數,讓它們公平地分享cpu,結果系統負荷就降了下來:

請注意上圖,看系統負荷(藍線)是如何降到cpu核數(紅線)以下的。在其它伺服器上,我們也看到了同樣的情況。既然總的工作量保持不變,那麼上圖中的效能改善只能歸功於上下文切換的減少。

排列不分先後:

1. 當效能遇到問題時,如果能在應用層進行計算和處理,那就把它從資料庫層拿出來。排序和分組就是典型的例子。在應用層做效能提升總是比在資料庫層容易的多。就像對於MySQL,sqlite更容易掌控。

2. 關於平行計算,如果能避免就盡量避免。如果無法避免,記住,能力越大,責任越大。如果有可能,盡量避免直接對執行緒操作。盡可能在更高的抽象層上操作。例如,在iOS中,GCD,分發和佇列操作是你的好朋友。人類的大腦沒有被設計成用來分析那些無窮臨時狀態——這是我的慘痛教訓所得。

###3. 盡可能簡化狀態,盡可能局部在地化。適用至上。 ######4. 短小可組合的方法是你的好朋友。 ######5. 程式碼註解是危險的,因為它們很容易更新不及時或給人誤導,但這不能成為不寫註解的理由。不要註釋雞毛蒜皮的事情,但如果需要,在某些特殊地方,戰略性的長篇註釋是需要的。你的記憶會背叛你,也許明天早上,也許會在一杯咖啡後。 ######6. 如果你認為一個用例場景也許“不會有問題吧”,它也許就是一個月後讓你在發布的產品中遭受慘痛失敗的地方。做一個懷疑主義者,測試,驗證。 ######7. 有疑問時,和團隊中所有相關人交流。 ###

8. 做正確的事——你通常會知道這指的是什麼。

9. 你的用戶並不傻,他們只是沒有耐心理解你的捷徑。

10. 如果一個開發人員沒有被安排長期的維護你們開發的系統,對他保持警惕。 80%的血、汗、淚水都是在軟體發布後的時間裡流的——那時你會變成一個厭世者,但也是更聰明的「行家」。

11. 任務清單是你的好朋友。

12. 主動讓你的工作更有樂趣,有時這需要你付出努力。

13. 悄無聲息的崩潰,我仍然會為此從惡夢中驚醒。監控,日誌,警報。清楚各種的假警報和不可避免的感覺鈍化。保持你的系統對故障的敏感和及時警報。

以上是如何為高負載網路最佳化Nginx和Node.js的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

nginx運行一段時間就掛掉怎麼回事 nginx運行一段時間就掛掉怎麼回事 Apr 14, 2025 am 07:18 AM

nginx 運行一段時間後掛掉的原因:1. 內存洩漏;2. 配置錯誤;3. 資源不足;4. 外部因素。解決方法:1. 診斷內存洩漏;2. 修復配置錯誤;3. 提供更多資源;4. 排除外部因素。

nginx負載均衡如何實現 nginx負載均衡如何實現 Apr 14, 2025 am 07:21 AM

Nginx 負載均衡通過 upstream 模塊定義後端服務器,並使用 location 塊將請求代理到這些服務器。支持輪詢、最少連接數、響應時間加權和 ip_hash 等負載均衡策略。配置示例包括定義 upstream 組和使用 proxy_pass 指令指向它。

nginx重新啟動的命令 nginx重新啟動的命令 Apr 14, 2025 am 07:27 AM

nginx 重新啟動命令:sudo systemctl restart nginx。其他相關命令包括:1.啟動:sudo systemctl start nginx;2.停止:sudo systemctl stop nginx;3.檢查狀態:sudo systemctl status nginx。

nginx autoindex是什麼意思 nginx autoindex是什麼意思 Apr 14, 2025 am 07:36 AM

Nginx Autoindex 是一種生成目錄列表 HTML 頁面的功能,用於在請求目錄而非文件時瀏覽文件、查看文件信息。它可通過配置選項定制,如顯示確切文件大小、本地時間和自定義頁面格式。優點包括方便瀏覽、易於配置和提供文件信息。缺點包括安全風險、性能影響和無法自定義頁面外觀。

nginx403什麼原因 nginx403什麼原因 Apr 14, 2025 am 07:39 AM

nginx 403 錯誤表示客戶端無權訪問資源。造成此問題的因素可能包括:權限設置、nginx 配置、CGI 腳本錯誤、.htaccess 文件或其他原因。排查步驟包括:檢查權限設置、審查 nginx 配置、測試 CGI 腳本、檢查 .htaccess 文件、排除防火牆或安全軟件,以及檢查服務器和文件系統。

nginx如何配置虛擬主機 nginx如何配置虛擬主機 Apr 14, 2025 am 08:15 AM

配置 nginx 虛擬主機允許在一個服務器上託管多個網站,每個網站擁有獨立域名和根目錄。具體配置步驟包括:創建虛擬主機配置文件配置服務器塊,指定服務器監聽端口、虛擬主機域名和文檔根目錄啟用虛擬主機,將配置文件鏈接到啟用目錄重新加載 nginx

nginx中如何重定向 nginx中如何重定向 Apr 14, 2025 am 08:42 AM

通過 Nginx 進行重定向的方法有 301 永久重定向(更新鏈接或移動頁面)和 302 臨時重定向(處理錯誤或臨時更改)。配置重定向涉及在 server 塊中使用 location 指令,高級功能包括正則表達式匹配、代理重定向和基於條件的重定向。重定向的常見用途包括更新 URL、處理錯誤、將 HTTP 重定向到 HTTPS,以及引導用戶訪問特定國家或語言版本。

nginx和web服務器的關係 nginx和web服務器的關係 Apr 14, 2025 am 07:09 AM

nginx 是一個輕量級、非阻塞的 Web 服務器和反向代理,常用於前端代理、負載平衡和緩存。它與 Web 服務器的關係通常是:前端代理:nginx 處理請求並轉發到後端服務器。負載平衡器:nginx 將請求分發到多台後端服務器。緩存:nginx 緩存經常訪問的文件以提高性能。

See all articles