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