網(wǎng)站開發(fā)編碼選擇一般是網(wǎng)絡(luò)營銷大師排行榜
一、故障現(xiàn)象
? 業(yè)務(wù)反饋服務(wù)異常,無法響應(yīng)請(qǐng)求,從系統(tǒng)日志?dmesg 或 /var/log/messages 看到大量以下記錄:kernel: nf_conntrack: table full, dropping packet.
二、問題分析
? 業(yè)務(wù)高峰期服務(wù)器訪問量大,內(nèi)核 netfilter 模塊 conntrack 相關(guān)參數(shù)配置過小不合理,導(dǎo)致 IP 包被丟掉,連接無法建立。
? nf_conntrack 模塊在 kernel 2.6.15(2006-01-03 發(fā)布) 被引入,支持 IPv4 和 IPv6,取代只支持 IPv4 的 ip_connktrack,用于跟蹤連接的狀態(tài),供其他模塊使用。需要 NAT 的服務(wù)都會(huì)用到它,例如防火墻、Docker 等。以 iptables 的?nat?和?state?模塊為例:
nat:根據(jù)轉(zhuǎn)發(fā)規(guī)則修改 IP 包的源/目標(biāo)地址,靠 conntrack 記錄才能讓返回的包能路由到發(fā)請(qǐng)求的機(jī)器。
state:直接用 conntrack 記錄的連接狀態(tài)(NEW/ESTABLISHED/RELATED/INVALID?等)來匹配防火墻過濾規(guī)則。
nf_conntrack 跟蹤所有網(wǎng)絡(luò)連接,記錄存儲(chǔ)在 1 個(gè)哈希表里。首先根據(jù)五元組算出哈希值,分配一個(gè)桶,如果有沖突就在鏈表上遍歷,直到找到一個(gè)精確匹配的。如果沒有匹配的則新建。連接記錄會(huì)在哈希表里保留一段時(shí)間,根據(jù)協(xié)議和狀態(tài)有所不同,直到超時(shí)都沒有收發(fā)包就會(huì)清除記錄。如果服務(wù)器比較繁忙,新連接進(jìn)來的速度遠(yuǎn)高于釋放的速度,把哈希表塞滿了,新連接的數(shù)據(jù)包就會(huì)被丟掉。此時(shí) netfilter 變成了一個(gè)黑洞, 這發(fā)生在3層(網(wǎng)絡(luò)層),應(yīng)用程序毫無辦法。
哈希表查看:
查看哈希表大小(桶的數(shù)量)
sysctl net.netfilter.nf_conntrack_buckets
查看最大跟蹤連接數(shù)
sysctl net.netfilter.nf_conntrack_max
#默認(rèn) nf_conntrack_buckets * 4
# max 是 bucket 的多少倍決定了每個(gè)桶里的鏈表有多長,因此默認(rèn)鏈表長度為 4
哈希表使用情況
sysctl net.netfilter.nf_conntrack_count
跟蹤連接記錄
四層協(xié)議類型和連接數(shù):
cat /proc/net/nf_conntrack | awk '{sum[$3]++} END {for(i in sum) print i, sum[i]}'
連接數(shù)最多的 10 個(gè) IP 地址:
cat /proc/net/nf_conntrack | awk '{print $7}' | cut -d "=" -f 2 | sort | uniq -c | sort -nr | head -n 10
?
三、處理過程
?哈希表擴(kuò)容:
nf_conntrack_max?的默認(rèn)值算法為:
CONNTRACK_MAX = RAMSIZE (in bytes) / 16384 / (ARCH / 32)
nf_conntrack_buckets?默認(rèn)值算法為:
HASHSIZE = CONNTRACK_MAX / 4
針對(duì)目前主機(jī)的配置建議配置(內(nèi)存:16GB系統(tǒng):64位):
CONNTRACK_MAX=(16*1024^3)/16384/(64/32)=524,288
HASHSIZE=524,288/4=131,072
給哈希表擴(kuò)容的影響:(主要是內(nèi)存)
計(jì)算內(nèi)存使用算法:
size_of_mem_used_by_conntrack (in bytes) = CONNTRACK_MAX * sizeof(struct ip_conntrack) + HASHSIZE * sizeof(struct list_head)
參數(shù)調(diào)整方法:
#寫入以下參數(shù)至/etc/sysctl.conf中,若已存在該參數(shù),直接調(diào)整大小即可
net.netfilter.nf_conntrack_buckets = 131072
net.netfilter.nf_conntrack_max = 524288
#配置永久生效
sysctl -w
四、經(jīng)驗(yàn)總結(jié)
? 一些服務(wù)的默認(rèn)配置參數(shù),隨著當(dāng)前業(yè)務(wù)規(guī)模的不斷增大可能已經(jīng)成為瓶頸,針對(duì)已出現(xiàn)有報(bào)錯(cuò)的苗頭后,發(fā)現(xiàn)后應(yīng)及時(shí)修正,并把修正后的配置參數(shù)作為規(guī)范加到集成規(guī)范和隱患整改中,防止再次發(fā)生同類故障案例。