使用 SQL Azure 从会话状态提供程序(实体框架)持续接收“超时时间已过”

Posted

技术标签:

【中文标题】使用 SQL Azure 从会话状态提供程序(实体框架)持续接收“超时时间已过”【英文标题】:Consistently receiving "timeout period elapsed" from session state provider (Entity Framework) with SQL Azure 【发布时间】:2012-12-19 19:56:44 【问题描述】:

始终我从指向 SQL Azure 数据库的 ASP.NET 4.5 Windows Azure Web 角色中的会话状态模块收到错误。会话状态模块正在使用 dbcontext。 例外情况包括。堆栈跟踪是:

System.Data.EntityException: The underlying provider failed on Open. ---> System.Data.SqlClient.SqlException: 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=2; handshake=14993;  ---> System.ComponentModel.Win32Exception: The wait operation timed out
--- End of inner exception stack trace ---
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()
at System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket()
at System.Data.SqlClient.TdsParser.ConsumePreLoginHandshake(Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean& marsCapable)
at System.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean withFailover)
at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover)
at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions)
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, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnectionOptions userOptions)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnectionOptions userOptions)
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& connection)
at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
--- End of inner exception stack trace ---
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
at System.Data.EntityClient.EntityConnection.Open()
at System.Data.Objects.ObjectContext.EnsureConnection()
at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source)
at System.Data.Entity.Internal.Linq.InternalSet`1.FindInStore(WrappedEntityKey key, String keyValuesParamName)
at System.Data.Entity.Internal.Linq.InternalSet`1.Find(Object[] keyValues)
at System.Web.Providers.DefaultSessionStateProvider.<>c__DisplayClass14.<SetAndReleaseItemExclusive>b__13()
at Microsoft.Practices.TransientFaultHandling.RetryPolicy.<>c__DisplayClass1.<ExecuteAction>b__0()
at Microsoft.Practices.TransientFaultHandling.RetryPolicy.ExecuteAction[TResult](Func`1 func)
at System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

你能帮我解决这个问题吗?

【问题讨论】:

你找到答案了吗?我似乎也打赌得到这些,但只是偶尔。 可能是重试延迟算法,例如:***.com/questions/17215377/… 【参考方案1】:

SQL Azure 提供有限的资源,因为每个数据库都存在于共享服务器中,这意味着如果另一个客户端在您正在工作的同一服务器上运行长查询,您的应用程序性能将会下降。

根据我两年使用 SQL Azure 的经验,您需要在 DAL 中实现一些重试逻辑,以使您的应用程序避免因此类错误而崩溃。此外,每个数据库最多只能同时连接 180 个连接,还有其他限制(如大小、管理等)。 180 之后的每个连接都会被拒绝。您必须小心保护您的应用程序免受 DoS 攻击!

没有可供 SQL Azure 的标准用户(如您或我)使用的选项(或配置)来减轻此限制(即使在企业数据库中)。在我作为 DBA 团队的公司中,我们与 Microsoft Ops 团队就许多与高事务负载相关的问题开了几张票,从他们那里收到的建议涉及沿多个数据库进行数据分区、索引、重试策略和延迟重试策略(用于连接/登录和查询) - 设置为 5 次重试;对于大型的 SELECTs / INSERTs / UPDATEs / DELETEs,根据记录的长度将 1000 到 10,000 组中的记录分段。

几年后,我们已将数据迁移到 IaaS(在 Azure 云上托管为 vM 的 SQL Server)。

我给你的建议是,在选择 SQL Azure 之前要慎重,想想优缺点!

好运!!

【讨论】:

以上是关于使用 SQL Azure 从会话状态提供程序(实体框架)持续接收“超时时间已过”的主要内容,如果未能解决你的问题,请参考以下文章

从 VS 2012 发布到 Azure 网站时,我的实体框架种子数据未插入 SQL Azure

如何将数据库从 SQL 服务器迁移到 SQL Azure,其中包含带有数据的 asp.net 成员资格提供程序

如何从实体框架 DbContext 收集当前的 SQL Server 会话 ID?

Azure 中 Spring Boot 应用程序的重定向/会话问题

使用Azure Automation Hybrid管理本地SQL Server备份状态

Azure Redis 缓存使用注意事项与排查问题文档整理