首頁 運維 Nginx 怎麼為高負載網路優化Nginx和Node.js

怎麼為高負載網路優化Nginx和Node.js

May 17, 2023 pm 03:13 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核數(紅線)以下的。在其它伺服器上,我們也看到了同樣的情況。既然總的工作量保持不變,那麼上圖中的效能改善只能歸功於上下文切換的減少。 ###

以上是怎麼為高負載網路優化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脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

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

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

docker容器名稱怎麼查 docker容器名稱怎麼查 Apr 15, 2025 pm 12:21 PM

可以通過以下步驟查詢 Docker 容器名稱:列出所有容器(docker ps)。篩選容器列表(使用 grep 命令)。獲取容器名稱(位於 "NAMES" 列中)。

nginx在windows中怎麼配置 nginx在windows中怎麼配置 Apr 14, 2025 pm 12:57 PM

如何在 Windows 中配置 Nginx?安裝 Nginx 並創建虛擬主機配置。修改主配置文件並包含虛擬主機配置。啟動或重新加載 Nginx。測試配置並查看網站。選擇性啟用 SSL 並配置 SSL 證書。選擇性設置防火牆允許 80 和 443 端口流量。

怎麼查看nginx是否啟動 怎麼查看nginx是否啟動 Apr 14, 2025 pm 01:03 PM

確認 Nginx 是否啟動的方法:1. 使用命令行:systemctl status nginx(Linux/Unix)、netstat -ano | findstr 80(Windows);2. 檢查端口 80 是否開放;3. 查看系統日誌中 Nginx 啟動消息;4. 使用第三方工具,如 Nagios、Zabbix、Icinga。

nginx怎麼配置雲服務器域名 nginx怎麼配置雲服務器域名 Apr 14, 2025 pm 12:18 PM

在雲服務器上配置 Nginx 域名的方法:創建 A 記錄,指向雲服務器的公共 IP 地址。在 Nginx 配置文件中添加虛擬主機塊,指定偵聽端口、域名和網站根目錄。重啟 Nginx 以應用更改。訪問域名測試配置。其他注意事項:安裝 SSL 證書啟用 HTTPS、確保防火牆允許 80 端口流量、等待 DNS 解析生效。

docker怎麼啟動容器 docker怎麼啟動容器 Apr 15, 2025 pm 12:27 PM

Docker 容器啟動步驟:拉取容器鏡像:運行 "docker pull [鏡像名稱]"。創建容器:使用 "docker create [選項] [鏡像名稱] [命令和參數]"。啟動容器:執行 "docker start [容器名稱或 ID]"。檢查容器狀態:通過 "docker ps" 驗證容器是否正在運行。

docker怎麼創建容器 docker怎麼創建容器 Apr 15, 2025 pm 12:18 PM

在 Docker 中創建容器: 1. 拉取鏡像: docker pull [鏡像名] 2. 創建容器: docker run [選項] [鏡像名] [命令] 3. 啟動容器: docker start [容器名]

nginx怎麼查版本 nginx怎麼查版本 Apr 14, 2025 am 11:57 AM

可以查詢 Nginx 版本的方法有:使用 nginx -v 命令;查看 nginx.conf 文件中的 version 指令;打開 Nginx 錯誤頁,查看頁面的標題。

怎麼啟動nginx服務器 怎麼啟動nginx服務器 Apr 14, 2025 pm 12:27 PM

啟動 Nginx 服務器需要按照不同操作系統採取不同的步驟:Linux/Unix 系統:安裝 Nginx 軟件包(例如使用 apt-get 或 yum)。使用 systemctl 啟動 Nginx 服務(例如 sudo systemctl start nginx)。 Windows 系統:下載並安裝 Windows 二進製文件。使用 nginx.exe 可執行文件啟動 Nginx(例如 nginx.exe -c conf\nginx.conf)。無論使用哪種操作系統,您都可以通過訪問服務器 IP

See all articles