測試結論
- 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;——支持websocketproxy_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,且最大值為65535linux內核是通過{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連接
百度介紹相關可自行測試。