2017-05-03 177 views
2

我们最近使用sql server实现了背板。我们创建底板的服务器也包含其他数据库。这些其他数据库由位于不同服务器上的不同应用程序访问。对于压力测试,我们实施了一个简单的信号客户端程序,每隔30秒向服务器发送一条消息。有两台服务器由负载平衡器处理。当客户数量很少时,背板可以很好地工作。Signalr SQL底板导致等待操作超时异常

问题是当客户端的数量更高。 (接近50或更多)。尝试将数据库服务器用于其他数据库的其他应用程序引发以下异常。

System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception: The wait operation timed out 
    --- End of inner exception stack trace --- 
    at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
    at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) 
    at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) 
    at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() 
    at System.Data.SqlClient.SqlDataReader.get_MetaData() 
    at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) 
    at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds) 
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite) 
    at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) 
    at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) 
    at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) 
    at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) 
    at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext) 
    at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) 
    --- End of inner exception stack trace --- 
    at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) 
    at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues) 
    at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) 
    at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5() 
    at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation) 
    at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) 
    at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0() 
    at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext() 
    at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source) 
    at System.Linq.Queryable.Count[TSource](IQueryable`1 source) 

由于此例外,所有其他应用程序因为无法访问数据库而中断。如果我们禁用背板,问题会立即解决。 (停止两台信号机服务器)。这是使用大量用户背板时的预期行为还是背板问题?

PS - 我们注意到,抛出这些异常的机器为w3wp.exe进程分配了超过3000个线程。看起来像他们被困在一个操作。

enter image description here

enter image description here

+0

您是否尝试过对SQL Server进行配置文件检查,发现是否有超过30秒的大量查询需要完成?任何性能调查? – cassandrad

+0

不幸的是,我们没有该数据库机器的访问权限,但是当禁用背板时,获取超时异常的相同查询完美地工作正常。 – janitha000

+0

通常情况下,底板不应该造成任何麻烦。而且,SQL服务器能够承受更大的工作量。你有没有检查连接数量和发送消息? – cassandrad

回答

1

如果你不使用异步调用,那么它是可行的,该消息的一个线程正在比预期更长的时间,而它正在等待返回另一个线程被卡住了,你是基本上锁螺纹。

2.可能的解决方案,我能想到的是:

1)确保你正在异步调用数据库。

2)确保在IIS服务器上有足够的线程安装。您至少需要12个,默认设置通常只有1.