接獲報案,案情如下:
- 某個按鈕後超過五分鐘才會有回應的網頁(註: 屬錯誤示範,改善方式請參考耗時Stored Procedure的ASP.NET Postback進度回報寫法),在測試台測試OK,移到正式台後,按鈕後五分鐘就會出現無法顯示網頁錯誤。
- 使用IE、Chrome、Firefox測試,IE與Firefox都是超過5分鐘就發生無法顯示網頁錯誤,Chrome卻可正常運作。
- 若由正式台伺服器同一網段的IE測試,則無逾時錯誤問題。
打閞茶包二哥--Microsoft Network Monitor,側錄一段IE連正式台重現錯誤的封包往來,很快找到原因:

上圖可看到300秒後Server端抛回一個TCP封包,紅框中的R為TCP RST Flag,表示伺服器端要求中止連線。而在IE接到此封包的時間,則好就是彈出無法顯示網頁的時機,一秒不差。
把同樣實驗搬回本機VM,等待時間即使拉長到7分鐘,也不會有連線中斷狀況。再加上報案資訊最後一點,從正式機同網段以IE測試不會出現逾時。推測問題出在Client與正式台間的網路設備,而該負載平衡設備曾有強切Oracle Session的前科。
最後的疑問,為什麼Chrome不會出錯? 就用Firefox、IE、Chrome的封包分析來說明吧!
Firefox
IE
Chrome
由往來封包可知,IE及Firefox在送出HTTP Request後,只會靜待HTTP Response回傳資料,而Chrome不同,在等待期間每隔45秒就會丟出一個TCP Keep Alive封包。依我推測,每45秒一次的TCP Keep Alive活動讓網路設備認定該連線仍在活動中,免除被強制斷線的命運。而修改測試ASP.NET網頁,每一分鐘以Response.Flush()方式抛回一個字元,IE/Firefox便不會在五分鐘時出錯。
至此,謎團都解開了。而我對這個案例的建議是: 修改ASP.NET程式,加入耗時Stored Procedure的ASP.NET Postback進度回報寫法,如此等待過程使用者能持續收到進度回饋改善使用體驗、也不會讓網路設備看不下去誤判閒置而強切連線,是較佳的解法。