很是抱歉!今天 12:03-12:52 ,因爲數據庫鏈接數異常突增超過1萬,達到了阿里雲RDS的最大鏈接數限制,影響了全站的正常訪問。由此給您帶來麻煩,請您諒解。html
在發現數據庫鏈接數突增的問題後,咱們一開始懷疑多是咱們的某些應用中產生太多ADO.NET鏈接引發的,可是對嫌疑的應用們進行重啓後,鏈接數依然高居不下。數據庫
後來,咱們回想起去年9月份遇到的一次數據庫問題,當時不少數據庫查詢超時,IOPS突增達到RDS的最大限制。開始咱們也是從應用層面下手,但怎麼也解決不了,後來實在沒辦法,試了試主備庫切換,切換後立馬神奇地恢復正常,而後就一直相安無事,直到今天。服務器
今天咱們再試試這一招吧!12:38開始進行主備庫切換,12:52左右鏈接數降到了1000如下,全站訪問恢復正常,這一招又一次神奇地發揮了做用。ide
恢復正常後,咱們分析了一下對應的應用日誌。post
在出現故障以前應用日誌就已經記錄了一些數據庫查詢超時:阿里雲
System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. This failure occured while attempting to connect to the Principle server. ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out
在故障期間出現了大量下面的錯誤日誌:url
1)沒法與阿里雲RDS創建TCP鏈接3d
System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)
2)達到ADO.NET鏈接池的最大鏈接數限制日誌
System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
3)達到阿里雲RDS的最大鏈接數限制,被拒絕登陸code
System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Logon failed for login 'xxx' due to trigger execution.
將這些錯誤日誌聯繫起來,咱們推斷數據庫鏈接數過萬並非應用中真的產生了大量的數據庫鏈接(並且發生的時間點是在午餐時間的訪問低峯),而是RDS出現了咱們所不知道的情況,形成大量數據庫操做沒法正常按時完成,所佔用的數據庫鏈接不能快速釋放,或者甚至是創建或釋放數據庫鏈接操做自己出了問題,形成數據庫鏈接愈來愈多。
看一下RDS的鏈接數在7天內的監控圖(見下圖),從4.2開始,鏈接數就開始異常,4.2-4.4天天的訪問量要明顯低於3.31-4.1,然而4.2的鏈接數居然高於3.31,以後愈來愈來高。可能咱們所用的RDS實例在4.2開始出現異常情況。
主備庫切換是將當前的RDS實例切換到了另一臺數據庫服務器上,切換後當即恢復正常也說明了以前RDS實例所在的服務器出了情況。並且,在今天下午的訪問高峯,在切換後的新服務器器上的最高鏈接數不超過3000。
雖然咱們的推斷只是沒有足夠證據的猜測,雖然阿里雲堅定認爲是咱們的應用產生了過多的數據庫鏈接,但咱們依然堅持對這個問題的推斷——是RDS的問題(注:後來事實證實是咱們推斷錯了,不是RDS的問題,是微軟.NET Core的一個bug引發的,詳見後續博文)。咱們沒法去驗證本身的推斷,咱們沒法躲避下次的一樣問題,但幸虧還有個救命稻草——主備庫切換,比提交工單還有效的救命稻草,當咱們急如燃眉地提交工單,等收到回覆時,咱們已經完成了主備庫切換,恢復了正常。
【更新】
這個問題的後續進展詳見 數據庫鏈接數過萬的真相,從阿里雲RDS到微軟.NET Core