間歇性 SQL 連接錯誤
我有一個 ASP.NET (Sitecore) 應用程序,日誌顯示我們客戶生產環境中的間歇性 SQL 連接錯誤。例外情況如下:
Exception: System.Data.SqlClient.SqlException Message: 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: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) Source: .Net SqlClient Data Provider at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, DbConnectionPool pool, String accessToken, Boolean applyTransientFaultHandling) at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions) at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection) at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection) at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions) at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry) at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry) at System.Data.SqlClient.SqlConnection.Open() at Sitecore.Data.DataProviders.Sql.DataProviderCommand..ctor(IDbCommand command, DataProviderTransaction transaction, Boolean openConnection) at Sitecore.Data.DataProviders.Sql.SqlDataApi.<>c__DisplayClass4.<CreateCommand>b__3() at Sitecore.Data.DataProviders.NullRetryer.Execute[T](Func`1 action, Action recover) at Sitecore.Data.DataProviders.Sql.SqlDataApi.<>c__DisplayClass12.<CreateReader>b__10() at Sitecore.Data.DataProviders.NullRetryer.Execute[T](Func`1 action, Action recover) at Sitecore.Data.DataProviders.Sql.SqlDataApi.CreateReader(String sql, Object[] parameters) at Sitecore.Data.DataProviders.Sql.SqlDataApi.<CreateObjectReader>d__6`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Sitecore.Eventing.EventQueue.ProcessEvents(Action`2 handler) at Sitecore.Eventing.EventProvider.RaiseQueuedEvents() Nested Exception Exception: System.ComponentModel.Win32Exception Message: The network path was not found 6420 16:53:53 ERROR Exception processing remote events from database: web Exception: System.Data.SqlClient.SqlException Message: 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: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) Source: .Net SqlClient Data Provider at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection) at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection) at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions) at System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry) at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry) at System.Data.SqlClient.SqlConnection.Open() at Sitecore.Data.DataProviders.Sql.DataProviderCommand..ctor(IDbCommand command, DataProviderTransaction transaction, Boolean openConnection) at Sitecore.Data.DataProviders.Sql.SqlDataApi.<>c__DisplayClass4.<CreateCommand>b__3() at Sitecore.Data.DataProviders.NullRetryer.Execute[T](Func`1 action, Action recover) at Sitecore.Data.DataProviders.Sql.SqlDataApi.<>c__DisplayClass12.<CreateReader>b__10() at Sitecore.Data.DataProviders.NullRetryer.Execute[T](Func`1 action, Action recover) at Sitecore.Data.DataProviders.Sql.SqlDataApi.CreateReader(String sql, Object[] parameters) at Sitecore.Data.DataProviders.Sql.SqlDataApi.<CreateObjectReader>d__6`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Sitecore.Eventing.EventQueue.ProcessEvents(Action`2 handler) at Sitecore.Eventing.EventProvider.RaiseQueuedEvents() Nested Exception Exception: System.ComponentModel.Win32Exception Message: The network path was not found如果您提供了無效的連接字元串,而您指定的伺服器不存在或無法在網路上訪問,則此錯誤很典型。但是,該站點在 99% 的時間都可以正常執行。
在此範例中,錯誤來自 Sitecore 的
RaiseQueuedEvents計劃任務,但其他地方也引發了異常,包括在訪問站點中的 URL 時,導致 http 500。有趣的是,它們是一波又一波的,也就是說,在幾秒鐘的時間內可能會有多達 100 個這樣的異常。
我們客戶的管理伺服器的基礎架構團隊非常堅持認為這不是網路問題,而是應用程式碼有問題,並報告說在這些異常似乎發生時數據庫流量有所增加:
> > (與通常的性能相比,所有這些都是明顯的峰值) - 在 10:10:14 - 如果使用者連接數從 60 增加到 90 - 在 10:10:14 - “批量請求/秒”的數量從大約 60 增加到 650 - 在 10:10:32 - “磁碟平均。“讀取時間”從 1 毫秒增加到 8.4 毫秒——在 10:10:32——網路使用率從 0.3% 飆升到 18% > > >
sql 監視器沒有註冊網路丟棄,對伺服器 CPU 使用率沒有影響。
我不是網路或 SQL 性能方面的專家,但對我來說,這些統計數據似乎並不合理,或者會導致後續連接嘗試收到“未找到網路路徑”異常;如果伺服器很忙,我希望收到超時異常?
我聯繫了 Sitecore 支持人員,他們迅速提出這是網路問題:
基於這些例外情況,它們似乎與 Sitecore 無關。消息清楚地表明您有某種網路錯誤,因此與您的基礎架構團隊一起進一步調查是合適的。我在我們的數據庫中查看了類似的問題,並且可以突出顯示以下領域。- 遠端連接被強制關閉/禁用 - 伺服器離線 - 與錯誤的安全上下文有關的事情。防火牆和防病毒軟體可能會影響這一點。
目前,我們處於爭執中;我的感覺是錯誤消息表明它一定是網路問題,但他們的團隊認為該網站在某種程度上被破壞了。
如何診斷問題所在?程式碼/站點核心可能有問題還是網路問題?
更新:網路詳細資訊
數據庫伺服器託管在不同的網路上,並且我相信通過 VLAN 聯網。伺服器是負載平衡的,我認為 可以使用防火牆而不是適當的負載平衡器來完成。
更新 2
問題是 SQL 被配置為允許 TCP 和命名管道。有時它會嘗試與不使用標準 SQL 埠的後者連接。解決方案是在連接字元串中為數據源/伺服器添加前綴,
Data Source=tcp:xxx.xxx.xx.xxx以始終確保它通過 TCP 連接
它與 Sitecore 無關,但我之前曾在另一個內容管理系統中看到過非常相似的情況。我也遇到了類似的挑戰,基礎設施人員確信數據庫伺服器很好,問題出在網站上。
我懷疑是網路問題,所以我的方法是:
- 我編寫了一個可以從命令行執行的 SQL 腳本,並且會顯示相同的連接問題。
- 我在 Web 伺服器上執行該腳本,並在數據庫伺服器本身上執行該腳本。我記錄了結果並進行了比較。
我的測試表明,當腳本在數據庫伺服器上執行時,根本無法重現該錯誤,但從 Web 伺服器的命令行執行時確實發生了該錯誤。這是支持我的預感的證據,即問題與連接相關,與網站或數據庫伺服器無關。
這將注意力集中在防火牆的設置上,該防火牆將網站的 DMZ 與 SQL 伺服器所在的內部網路分開。這個防火牆是一對負載平衡的——我們最終能夠找到一個細微的配置差異,它導致第二個盒子終止了通過第一個盒子啟動的連接。
該特定問題似乎不太可能對您造成問題 - 但您可能會發現提出測試的總體方法可以幫助定位問題的原因有幫助嗎?