測試結論
- nginx最多隻能維持(65535*後端伺服器IP個數)條websocket的長連線,如果後端websocket伺服器IP只有一個,那麼就只能最多支援65535條連線。瓶頸就產生在了nginx上
- 建議採用LVS的DR模式來做負載均衡,這樣最大長連線數目就只和websocket伺服器資源(主要是記憶體)有關了,單臺websocket伺服器很輕鬆可以支撐百萬級連線
websocket 相關配置
<Connector port="9999" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" acceptCount="150000"
maxThreads="2000" maxConnections="150000" enableLookups="false" redirectPort="8443" />
複製程式碼
-
connectionTimeout——預設設定為20秒。通過修改該引數,可以修改tomcat的請求超時時間
-
acceptCount——當tomcat的執行緒數達到maxThreads後,新的請求就會排隊等待,超過排隊數的請求會被拒絕,acceptCount最好大於等於maxThreads
-
maxThreads:
(1)、部署的程式偏計算型,主要利用cpu資源,應該將該引數設定小一點,減小同一時間搶佔cpu資源的執行緒個數。 (2)、部署的程式對io、資料庫佔用時間較長,執行緒處於等待的時間較長,應該將該引數調大一點,增加處理個數。
-
maxConnections——這個值表示最多可以有多少個socket連線到tomcat上。NIO模式下預設是10000
-
enableLookups——為了消除DNS查詢對效能的影響我們可以關閉DNS查
Nginx
location ^~ /wnhz/websocket/ {
proxy_connect_timeout 60s;——該指令設定與upstream server的連線超時時間,有必要記住,這個超時不能超過75秒
proxy_read_timeout 3600s;——該指令設定與代理伺服器的讀超時時間。它決定了nginx會等待多長時間來獲得請求的響應。這個時間不是獲得整個response的時間,而是兩次reading操作的時間
proxy_send_timeout 60s; ——這個指定設定了傳送請求給upstream伺服器的超時時間。超時設定不是為了整個傳送期間,而是在兩次write操作期間。如果超時後,upstream沒有收到新的資料,nginx會關閉連線
proxy_http_version 1.1;——支援websocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_pass http://test/websocket/;
}
--------------------- 官方配置--------------------------------------
location /chat/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
複製程式碼
用nginx做websocket的反向代理資源瓶頸原理
- 記憶體(相關資料結構的儲存)、cpu、網路
記憶體的佔用分兩部分,一部分是核心中tcp協議棧結構佔用的記憶體,一部分是nginx中維持雙向連線資料結構佔用的記憶體
按照理想狀況,一條tcp連線的資料結構在記憶體中佔用大約4KB左右,nginx的記憶體佔用,沒有統計相關的結構體,這裡就等於2KB(nginx的記憶體利用非常高效,有記憶體池)
對於現在的伺服器來說記憶體、cpu、網路都不會是瓶頸,因此這裡不做討論
複製程式碼
- 檔案描述符數量
可能需要調整核心引數,檔案描述符的數量其實也是和記憶體相關的,因為每開啟一個tcp連線,就得佔用一個檔案描述符。
核心引數:fs.file-max
這是和系統資源相關的,也不會是瓶頸
複製程式碼
- 埠號數量
核心引數為:net.ipv4.ip_local_port_range,且最大值為65535
linux核心是通過{local_ip, local_port, remote_ip, remote_port}這個四元組來標識一條唯一的tcp連線的。
1)對於websocket伺服器自身而言,local_ip, local_port是確定的,在記憶體、cpu足夠的情況下,其可以支撐 (client_ip數量*2^16)條連線。也就是說只要伺服器資源足夠,一定不會是瓶頸。
2)對於nginx伺服器來說,local_ip, local_port也是確定的,不同的是,它還要作為client去連線websocket伺服器,這是要佔用一個埠的。
因此,nginx能支撐的websocket連線數最大為:(代理的websocket伺服器IP數量*2^16),如果只有一個websocket伺服器IP,那麼就只有65536,去掉0埠,就只有65535.
複製程式碼
Linux測試5wWebSocket連線
百度介紹相關可自行測試。