網(wǎng)站的Android應(yīng)用向服務(wù)器發(fā)送請(qǐng)求時(shí),經(jīng)常出現(xiàn)網(wǎng)路超時(shí)的現(xiàn)象,而IPhone應(yīng)用卻一切正常。
起初懷疑是我們Android應(yīng)用中的BUG,但在排查過程中發(fā)現(xiàn),通過Andorid瀏覽器訪問網(wǎng)站的WEB頁(yè)面同樣會(huì)出現(xiàn)網(wǎng)絡(luò)超時(shí)的問題。
這一發(fā)現(xiàn)讓我們將排查的對(duì)象轉(zhuǎn)移到服務(wù)器的配置上。最后確定問題的原因是我們將tcp_tw_recycle和tcp_timestamps同時(shí)打開了。
之前我們?yōu)榱朔?wù)器性能優(yōu)化,在nginx所在的機(jī)器上修改了內(nèi)核的tcp設(shè)置,開啟了tw_reuse和tw_recycle。
net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1
tcp_timestamps在CentOS中默認(rèn)是打開的。
在linux內(nèi)核中,如果tcp_tw_recyle和tcp_timestamps同時(shí)開啟,內(nèi)核會(huì)要求在60內(nèi)同一源發(fā)出的tcp請(qǐng)求的timestamp是遞增的。NAT下的機(jī)器共享同一個(gè)對(duì)外IP,每個(gè)機(jī)器的timestamp是隨機(jī)生成的,這就導(dǎo)致當(dāng)NAT下多個(gè)client同時(shí)訪問服務(wù)器時(shí),timestamp大的client能獲得響應(yīng),而其他client被拒絕。
可是為什么IPhone應(yīng)用不受這一限制呢?
原因是tcp_timestamp在IPhone中默認(rèn)是關(guān)閉的,在Android系統(tǒng)中默認(rèn)卻是開啟的。
解決辦法:將net.ipv4.tcp_tw_recyle設(shè)為0, sysctl -p。
重設(shè)之后,該問題解決。