我们有一个生产网站,其中混合了经典的ASP、内联的.Net和已编译的.Net,它们与同一物理服务器上的SQL Server实例进行通信,一切工作正常。为了测试一些新功能,我创建了一个QA版本的网站,并将其设置为连接到托管在另一台物理服务器上的VM上的数据库。它们处于不同的网络(DMZ / 内部),但都在千兆位的同一机架上,因此连接速度不应该是问题。
我们遇到的问题是QA版本会工作一段时间,然后突然崩溃,直到我重新启动应用程序池和网站。这不是负载问题,因为只有我和其他两个人测试这个流程,而且我已经确认了托管QA数据库的服务器没有资源问题(16GB RAM,3.2GB正在使用,处理器利用率在2%左右)。所有页面的变体(经典ASP、内联 .Net 和已编译的 .Net 页面)都会出现特定的错误(如下所示)。根据我所做的所有研究,我一直被指回防火墙问题,但即使我们打开了两个服务器之间的所有端口,它仍然会发生。最奇怪的部分是当我们在ASA(5515-X)上启用跟踪时,它几乎看不到任何流量,有时站点会立即返回该错误,而其他时候则需要30秒以上。这些页面没有进行任何复杂的查找(死亡的页面总共获取大约60条记录)。以下是完整的错误/堆栈跟踪:
[Win32Exception (0x80004005): The wait operation timed out]
[SqlException (0x80131904): Connection Timeout Expired. The timeout period elapsed while attempting to consume the pre-login handshake acknowledgement. This could be because the pre-login handshake failed or the server was unable to respond back in time. The duration spent while attempting to connect to this server was - [Pre-Login] initialization=21008; handshake=12; ]
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +6749670
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +815
System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error) +817
System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync() +344
System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket() +48
System.Data.SqlClient.TdsParser.ConsumePreLoginHandshake(Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean& marsCapable) +126
System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean withFailover) +693
System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover) +219
System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout) +6777754
System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance) +6778255
System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData) +878
System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions) +1162
System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions) +72
System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) +6781425
System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection) +103
System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection) +2105
System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) +116
System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection) +1089
System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions) +6785863
System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry) +233
System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry) +278
System.Data.SqlClient.SqlConnection.Open() +239
System.Web.UI.Control.LoadRecursive() +71
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3178
我想展示一段代码块,但由于一旦这样做所有页面都会开始出问题,所以这并没有什么好处。在生产环境中这一切都很顺利,唯一的区别是虚拟机在不同的物理主机上,但鉴于这都是新的硬件,没有理由出现问题。
我在这里看到多个使用exec sp_updatestats
和dbcc freeproccache
的方法,但是两者都似乎没有什么作用。
我完全迷失了,有什么建议吗?