Ubuntu16.04內核參數調優

一、背景

最近在測試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~~~陷入沉思~~~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章