項目開了個P2P服務器,但是運行一段時間就會出現丟包問題,具體表現為:
1、udp丟包嚴重(一分鍾收發分別1.5W)
2、ssh(用於運維指令)連接不上該服務器(超時)
3、服務器運行好像沒什么異常,udp假連接數比tcp連接數少(正常應該相近)
首先開始懷疑是不是客戶端有bug,查log發現某段時間有個別客戶端發大量心跳包,開始懷疑這個原因導致服務異常。在多次關服開服后沒出現這個問題,但是服務器運行一段時間依舊出現上述異常,排除這個原因。
既然不是客戶端導致的。。
就開始在自身找原因,接着懷疑是不是最大連接數、最大文件打開數,查了一下服務器設置:
ulimit -n //可以打開最大文件描述符的數量
65536
ulimit -a //顯示當前所有的 limit 信息
time(seconds) unlimited
file(blocks) unlimited
data(kbytes) unlimited
stack(kbytes) 8192
coredump(blocks) unlimited
memory(kbytes) unlimited
locked memory(kbytes) 64
process 516037
nofiles 65536
vmemory(kbytes) unlimited
locks unlimited
cat /proc/sys/fs/nr_open //單進程最大文件限制
1048576
cat /proc/sys/fs/file-max //系統最大文件限制
6605234
再看下服務器現在相關信息:
lsof -n //查看服務器文件打開數信息
ps -aef //進程信息
發現無論是文件描述符打開數還是文件打開數都沒超標---陷入僵局。
覺得應該是系統某個設置不當導致的,但是又無從查起,查 /car/log/messages 里面的信息應該能查到點端倪,可是沒權限。(dmesg 命令好像可以查看)
后來咨詢其他小組,發現他們也遇到過一樣的問題,問題來自於跟蹤連接表的限制----nf_conntrack/ip_conntrack。
理解nf_conntrack和調整nf_conntrack_max :nf_conntrack 工作在 3 層,支持 IPv4 和 IPv6,而 ip_conntrack 只支持 IPv4。
目前,大多的 ip_conntrack_* 已被 nf_conntrack_* 取代,很多 ip_conntrack_* 僅僅是個 alias,原先的 ip_conntrack 的 /proc/sys/net/ipv4/netfilter/ 依然存在,但是新的 nf_conntrack 在 /proc/sys/net/netfilter/ 中,這個應該是做個向下的兼容。
nf_conntrack/ip_conntrack 跟 nat 有關,用來跟蹤連接條目,它會使用一個哈希表來記錄 established 的記錄。nf_conntrack 在 2.6.15 被引入,而 ip_conntrack 在 2.6.22被移除,如果該哈希表滿了,就會出現問題來。
查看系統默認跟蹤連接表限制:
cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max //最大
cat /proc/sys/net/ipv4/netfilter/ip_conntrack_tcp_timeout_established //保存時間
cat /proc/sys/net/ipv4/netfilter/ip_conntrack_count //當前
查看了以后,發現運行一段時間后 跟蹤連接表的確是滿了,導致文章開始所述的情況出現,而 ip_conntrack_max 有個建議值:
CONNTRACK_MAX = RAMSIZE(in bytes)/16384/(ARCH/32),如32G內存可以設置1048576
臨時修改該值:
echo 1048576> /proc/sys/net/ipv4/netfilter/ip_conntrack_max
p2p服務器重啟后運行恢復正常。
參考引用:
http://itoedr.blog.163.com/blog/static/120284297201451013130868/