網站故障公告3:應該找到了問題的真正原因


根據故障期間的錯誤信息:

Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.

找到了這三篇博文:

1. ADO.NET application connecting to a mirrored SQL Server Database may timeout long before the actual connection timeout elapses, sometimes within milliseconds

2. Interesting SQL Server Mirroring Problem

3. You may see an instant timeout when connecting to a SQL Server Mirrored database from a .Net application

談到的都是SQL Server數據庫鏡像引起的"Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding." 尤其是第3篇中的一段文字:

As per the Connection Retry Algorithm for Mirroring, SqlClient code takes the connection timeout and multiplies it by 0.08 to determine the milliseconds to wait for first read (SniReadSync call). Now if this first SniReadSync fails due to a timeout (due to a slow response from the server), the connection is incorrectly set to a doomed state by the sqlClient .NET Provider and this causes the connection attempt to prematurely fail before the entire connection timeout expires.

聯想到阿里雲RDS與我們之前自己的物理服務器、阿里雲雲服務器時最大的不同之處是:阿里雲RDS使用了SQL Server數據庫鏡像。

立即眼前一亮!問題的真正原因就在這——ADO.NET對SQL Server數據庫鏡像處理上的bug。

故障是這么發生的:

1. 我們在博客程序的連接字符串中設置的是Connect Timeout=30(默認是15);

2. SqlClient將 30(Connect Timeout) × 0.08 = 2.4s 作為超時時間發起一次數據庫連接操作;

3. 對於SQL Server數據庫鏡像的場景,SqlClient只對Principal數據庫發起1次且僅此1次數據庫連接操作(不合理,至少失敗時重試一次);

4. 如果超時,SqlClient就會去連接“連接字符串”中通過Failover Partner指定的鏡像數據庫;(4月17日故障時就是發生了超時情況)

5. 而我們在連接字符串中沒有指定Failover Partner,SqlClient也沒有鏡像數據庫可連,於是SqlClient就自以為是地Timeout。

這是ADO.NET的一個bug,微軟在2011年就確認了這個bug,說是在下一版本中(也就是現在的.NET Framework 4.5)會修復這個問題。

Microsoft has confirmed that this is a problem in the current release of ADO.NET. This issue will be fixed in ADO.NET version, ships with Visual Studio 2011.

而我們的博客程序用的是.NET Framework 4.0,沒能躲開這個bug的魔爪。

目前還不知道.NET Framework 4.5是不是真的解決了這個問題。

真沒想到,最終竟然是被微軟坑的!

臨時解決方法:在連接字符串中設置Connect Timeout=150,並從網絡與數據庫層面盡量減少連接時間。

補充:有人在阿里雲論壇上提到“之前用RDS時就會偶爾出現秒級以上的延時”,這可能也是一個肇事者。

更新:“問題的真正原因”背后的真正問題是為什么數據庫連接會超時(注:只是連接,查詢還沒開始)?

相關博文:

網站故障公告1:使用阿里雲RDS之后一個讓人欲哭無淚的下午

網站故障公告2:找到問題的重要線索


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM