1. 程式人生 > >【轉】轉 Linux調優方案,sysctl.conf的設定

【轉】轉 Linux調優方案,sysctl.conf的設定

**************************************************************************************************************
轉載自:http://bbs.chinaunix.net/thread-2318039-1-1.html
問題表現就是epoll這個服務端對10000的併發請求處理特別慢,甚至還出現很多客戶連線超時的情況!但是順序的一個個請求卻沒有問題。

測試如下:
首先是1個程序,順序10000個請求。服務端沒問題,很快速完成。

然後是10000個程序,每個程序1個請求,開始都還正常,可是過一會服務端accept就阻塞了,大概有1-2s,之後又返回,有時候還會出現客戶端連線超時的問題,但是這樣測30章那個執行緒池(300個執行緒)的服務端程式碼,不管怎麼測都不會有問題。

按理說accept應該能一直返回才對呀,為什麼中途會阻塞呢?是核心引數問題?
之前也試過把listenfd也新增到epoll裡,listenfd不是ET模式。也有這樣的問題。

分析了很多可能:
?        epoll本身處理效率的問題(這個自己都不信)
?        服務端完成客戶的處理請求太耗時,導致沒有時間讓accept返回其他客戶連線(這是個最簡單的處理,應該也不會)
?        單臺機器測試,所以產生了太多的TIME_WAIT導致客戶無法連線導致超時(之前以為是這個原因)
?        核心的一些限制問題,服務端不能同時處理太多連線(可能的原因)

最終才發現真正原因!!!
原來上面這個伺服器程式碼listen指定的backlog連線完成佇列引數太小,只有32,導致高併發的時候,伺服器的連線完成佇列在極短的時間內被填滿了,而accept的處理速度跟不上佇列填滿的速度,導致佇列始終是滿的,然後就不理會客戶的其他連線請求,導致了客戶connect超時,並且處理效率低下。
而執行緒池的backlog有1024,不過受限於核心引數的預設值最大128,所以執行緒池這個的backlog實際是128(見man listen),再加上300個執行緒,每個執行緒獨自accpet,所以能很快從完成佇列中取得連線,客戶的connect也不會超時了,如果把執行緒數改為1個,客戶連線也會超時。

詳細資訊可以man listen  同時man tcp 裡面有很多限制對伺服器來說需要改的。

一般設定:
1 #sudo vi /etc/sysctl.conf 
#在最後面編輯新增以下內容: 

#預設socket寫buffer,可參考的優化值:873200/1746400/3492800
net.core.wmem_default = 1746400

#最大socket寫buffer,可參考的優化值:1746400/3492800/6985600
net.core.wmem_max = 3492800

#預設socket讀buffer,可參考的優化值:873200/1746400/3492800
net.core.rmem_default = 1746400

#最大socket讀buffer,可參考的優化值:1746400/3492800/6985600
net.core.rmem_max = 3492800

#進入包的最大裝置佇列.預設是1000,對重負載伺服器而言,該值太低,可調整到16384/32768/65535
net.core.netdev_max_backlog = 32768

#listen()的預設引數,掛起請求的最大數量.預設是128.對繁忙的伺服器,增加該值有助於網路效能.可調整到8192/16384/32768
net.core.somaxconn = 16384

#每個socket buffer的最大補助快取大小,預設10K(10240),也可調整到20k(20480),但建議保留
net.core.optmem_max = 10240

#表示用於向外連線的埠範圍.預設情況下過窄:32768到61000,改為1024到65535
net.ipv4.ip_local_port_range = 1024 65535

#TCP寫buffer,可參考的優化值:873200/1746400/3492800/6985600
net.ipv4.tcp_wmem = 873200 1746400 3492800

#TCP讀buffer,可參考的優化值:873200/1746400/3492800/6985600
net.ipv4.tcp_rmem = 873200 1746400 3492800

#net.ipv4.tcp_mem[0]:低於此值,TCP沒有記憶體壓力.
#net.ipv4.tcp_mem[1]:在此值下,進入記憶體壓力階段.
#net.ipv4.tcp_mem[2]:高於此值,TCP拒絕分配socket.
#上述記憶體單位是頁,而不是位元組.可參考的優化值是:78643200/104857600/157286400
net.ipv4.tcp_mem = 78643200 104857600 157286400

#進入SYN包的最大請求佇列.預設1024.對重負載伺服器,增加該值顯然有好處.可調整到16384/32768/65535
net.ipv4.tcp_max_syn_backlog = 32768

#TCP失敗重傳次數,預設值15,意味著重傳15次才徹底放棄.可減少到5,以儘早釋放核心資源
net.ipv4.tcp_retries2 = 5

#以下3個引數與TCP KeepAlive有關.預設值是:
#tcp_keepalive_time = 7200 seconds (2 hours)
#tcp_keepalive_probes = 9
#tcp_keepalive_intvl = 75 seconds
#意思是如果某個TCP連線在idle 2個小時後,核心才發起probe.如果probe 9次(每次75秒)不成功,核心才徹底放棄,認為該連線已失效
#對伺服器而言,顯然上述值太大.可調整到:
net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 30

#表示開啟SYN Cookies,當出現SYN等待佇列溢位時,啟用cookies來處理,可防範少量SYN攻擊,預設為0,表示關閉
net.ipv4.tcp_syncookies = 1

#表示如果套接字由本端要求關閉,這個引數決定了它保持在FIN-WAIT-2狀態的時間
net.ipv4.tcp_fin_timeout = 30

#表示開啟重用,允許將TIME-WAIT sockets重新用於新的TCP連線,預設為0,表示關閉
#net.ipv4.tcp_tw_reuse = 1

#表示開啟TCP連線中TIME-WAIT sockets的快速回收,預設為0,表示關閉
#net.ipv4.tcp_tw_recycle = 1

#表示系統同時保持TIME_WAIT套接字的最大數量,如果超過這個數字,TIME_WAIT套接字將立刻被清除並列印警告資訊
#預設為180000,建議使用預設值,不建議調小
#net.ipv4.tcp_max_tw_buckets = 180000

#其它的一些設定
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2

儲存退出:
2 #sudo /sbin/sysctl -p

***************************************************************************************