一、背景
最近在測試EMQ伺服器在大量連接配接下cpu、記憶體的情況,這也算高并發相關吧。開發工具為IDEA,采用的mqtt-client是基于netty編寫的。在window上隻有65535個端口,在使用IDEA測試連接配接數到16000左右就占用光了,即使後來經過tcp參數調優後有60000出頭的連接配接數。見到網上使用linux測試連接配接數的居多,就在電腦上裝了個Ubuntu16.04的虛拟機嘗試。
二、過程
Ps:虛拟機網絡不能使用nat模式,得使用橋接,不然的話不還是共享主機ip,占用的還是你主機的端口,這毫無意義。具體橋接的方式可參考我前兩天寫的文章。
虛拟機參數:記憶體2G、硬碟20G、單核、橋接模式(自動)
主機參數:win10、記憶體12G、四核
沒有進行優化下有28000+的連接配接數,比起window簡直好太多了,淚流滿面。當然,這遠遠不夠。百度了一波,主要就那麼幾種方法,修改單程序最大打開檔案數限制或者tcp參數優化
1、修改單程序最大打開檔案數限制:
檢視:ulimit -n
修改:ulimit -n 65535
僅在目前打開的終端視窗才有效,新(舊)打開的無效。
2、tcp參數優化
#表示開啟重用。允許将TIME-WAIT sockets重新用于新的TCP連接配接,預設為0,表示關閉;
net.ipv4.tcp_syncookies = 1
#一個布爾類型的标志,控制着當有很多的連接配接請求時核心的行為。啟用的話,如果服務超載,核心将主動地發送RST包。
net.ipv4.tcp_abort_on_overflow = 1
#表示系統同時保持TIME_WAIT的最大數量,如果超過這個數字,TIME_WAIT将立刻被清除并列印警告資訊。
#預設為180000,改為6000。對于Apache、Nginx等伺服器,此項參數可以控制TIME_WAIT的最大數量,伺服器被大量的TIME_WAIT拖死
net.ipv4.tcp_max_tw_buckets = 6000
#有選擇的應答
net.ipv4.tcp_sack = 1
#該檔案表示設定tcp/ip會話的滑動視窗大小是否可變。參數值為布爾值,為1時表示可變,為0時表示不可變。tcp/ip通常使用的視窗最大可達到65535 位元組,對于高速網絡.
#該值可能太小,這時候如果啟用了該功能,可以使tcp/ip滑動視窗大小增大數個數量級,進而提高資料傳輸的能力。
net.ipv4.tcp_window_scaling = 1
#TCP接收緩沖區
net.ipv4.tcp_rmem = 4096 87380 4194304
#TCP發送緩沖區
net.ipv4.tcp_wmem = 4096 66384 4194304
#Out of socket memory
net.ipv4.tcp_mem = 94500000 915000000 927000000
#該檔案表示每個套接字所允許的最大緩沖區的大小。
net.core.optmem_max = 81920
#該檔案指定了發送套接字緩沖區大小的預設值(以位元組為機關)。
net.core.wmem_default = 8388608
#指定了發送套接字緩沖區大小的最大值(以位元組為機關)。
net.core.wmem_max = 16777216
#指定了接收套接字緩沖區大小的預設值(以位元組為機關)。
net.core.rmem_default = 8388608
#指定了接收套接字緩沖區大小的最大值(以位元組為機關)。
net.core.rmem_max = 16777216
#表示SYN隊列的長度,預設為1024,加大隊列長度為10200000,可以容納更多等待連接配接的網絡連接配接數。
net.ipv4.tcp_max_syn_backlog = 1020000
#每個網絡接口接收資料包的速率比核心處理這些包的速率快時,允許送到隊列的資料包的最大數目。
net.core.netdev_max_backlog = 862144
#web 應用中listen 函數的backlog 預設會給我們核心參數的net.core.somaxconn 限制到128,而nginx 定義的NGX_LISTEN_BACKLOG 預設為511,是以有必要調整這個值。
net.core.somaxconn = 262144
#系統中最多有多少個TCP 套接字不被關聯到任何一個使用者檔案句柄上。如果超過這個數字,孤兒連接配接将即刻被複位并列印出警告資訊。
#這個限制僅僅是為了防止簡單的DoS 攻擊,不能過分依靠它或者人為地減小這個值,更應該增加這個
net.ipv4.tcp_max_orphans = 327680
#時間戳可以避免序列号的卷繞。一個1Gbps 的鍊路肯定會遇到以前用過的序列号。時間戳能夠讓核心接受這種“異常”的資料包。這裡需要将其關掉。
net.ipv4.tcp_timestamps = 0
#為了打開對端的連接配接,核心需要發送一個SYN 并附帶一個回應前面一個SYN 的ACK。也就是所謂三次握手中的第二次握手。這個設定決定了核心放棄連接配接之前發送SYN+ACK 包的數量。
net.ipv4.tcp_synack_retries = 1
#在核心放棄建立連接配接之前發送SYN 包的數量。
net.ipv4.tcp_syn_retries = 1
#表示開啟重用。允許将TIME-WAIT sockets重新用于新的TCP連接配接,預設為0,表示關閉;
net.ipv4.tcp_tw_reuse = 1
#修改系統預設的 TIMEOUT 時間。
net.ipv4.tcp_fin_timeout = 15
#表示當keepalive起用的時候,TCP發送keepalive消息的頻度。預設是2小時,建議改為20分鐘。
net.ipv4.tcp_keepalive_time = 30
#表示用于向外連接配接的端口範圍。預設情況下很小:32768到61000,改為1024到65535。(注意:這裡不要将最低值設的太低,否則可能會占用掉正常的端口!)
net.ipv4.ip_local_port_range = 1024 65535
#以下可能需要加載ip_conntrack子產品 modprobe ip_conntrack ,有文檔說防火牆開啟情況下此子產品失效
#縮短established的超時時間
net.netfilter.nf_conntrack_tcp_timeout_established = 180
#CONNTRACK_MAX 允許的最大跟蹤連接配接條目,是在核心記憶體中netfilter可以同時處理的“任務”(連接配接跟蹤條目)
net.netfilter.nf_conntrack_max = 1048576
net.nf_conntrack_max = 1048576
最後兩個參數在我的Ubuntu16.04上找不到,是因為沒有開這個子產品,使用指令“sudo modprobe nf_conntrack”即可。
添加完成後,執行下面指令
/sbin/sysctl -p /etc/sysctl.conf
/sbin/sysctl -w net.ipv4.route.flush=1
三、結果
重新測試後發現還是有效果的,測了幾次最多的連接配接數是56000+。說好的數十萬連接配接呢,别人呢個做到我咋不行QAQ~~~陷入沉思~~~