2011-12-22 105 views
210

我的网站上有很多用户(每天20000-60000),这是一个移动文件的下载网站。我可以远程访问我的服务器(Windows Server 2008-R2)。
我收到了“服务器不可用”错误,但现在看到连接超时错误。
我对此不熟悉 - 为什么会发生,我该如何解决?下面超时已过期。操作完成之前超时的时间或服务器没有响应。声明已被终止

完整的错误是:

Server Error in '/' Application. Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.]
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +404
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +412
System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1363
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +6387741
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +6389442
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +538
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +689
System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +327
NovinMedia.Data.DbObject.RunProcedure(String storedProcName, IDataParameter[] parameters, Int32& rowsAffected) +209
DataLayer.OnlineUsers.Update_SessionEnd_And_Online(Object Session_End, Boolean Online) +440
NiceFileExplorer.Global.Application_Start(Object sender, EventArgs e) +163

[HttpException (0x80004005): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +4052053
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +191
System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +352
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +407
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +375

[HttpException (0x80004005): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +11686928 System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +141 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +4863749


编辑应答后:
Application_StartGlobal.asax是象下面这样:

protected void Application_Start(object sender, EventArgs e) 
{ 
    Application["OnlineUsers"] = 0; 

    OnlineUsers.Update_SessionEnd_And_Online(
     DateTime.Now, 
     false); 

    AddTask("DoStuff", 10); 
} 

被调用存储过程是:

ALTER Procedure [dbo].[sp_OnlineUsers_Update_SessionEnd_And_Online] 
    @Session_End datetime, 
    @Online bit 
As 
Begin 
    Update OnlineUsers 
    SET 
     [Session_End] = @Session_End, 
     [Online] = @Online 

End 

我有让在线用户两种方法:使用Application["OnlineUsers"] = 0;

  • 另外一个使用数据库
  • 所以,方法#2我重置所有OnlineUsers在Application_Start

    1. 。该表中有超过482,751条记录。

    +0

    作为这里说的[默认为15秒](http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectiontimeout.aspx) – V4Vendetta 2011-12-22 10:36:42

    +0

    更好地使根原因分析,造成这样的问题有各种原因。最基本的是查询的复杂结构。当我在表格中获取以十六进制值存储的图像时,我遇到了同样的问题。 – 2015-06-29 10:21:45

    +0

    除了上面的原因,我会再添加一个:锁定超时:https://docs.microsoft.com/en-us/sql/t-sql/statements/set-lock-timeout-transact-sql如果这线程等待锁定时间过长,会基于上述文件超时。 – 2017-05-15 20:56:42

    回答

    249

    看起来您的查询花费的时间比应该多。 从你的堆栈跟踪和你的代码你应该能够确切地确定是什么查询。

    这种超时类型可能有三个原因;

    1. 有一个僵局地方
    2. 数据库的统计数据和/或查询计划缓存是不正确的
    3. 查询过于复杂,需要调整

    死锁可能很难修复,但很容易确定是否是这种情况。使用Sql Server Management Studio连接到您的数据库。在左侧窗格中,右键单击服务器节点并选择活动监视器。看看正在运行的进程。 通常情况下,大多数会空闲或运行。发生问题时,您可以通过进程状态识别任何被阻塞的进程。如果右键单击该进程并选择详细信息它会显示进程执行的最后一个查询。

    第二个问题将导致数据库使用次优查询计划。它可以通过清除统计来解决:

    exec sp_updatestats 
    

    如果不工作,你也可以尝试

    dbcc freeproccache 
    

    你不应该这样做,当你的服务器负载过大时,因为它会招致暂时由于所有存储过程和查询在第一次执行时都会重新编译,所以性能很高。 但是,由于您声明问题发生在有时,并且堆栈跟踪指示您的应用程序正在启动,所以我认为您运行的是仅偶尔运行的查询。通过强制SQL Server不要重复使用先前的查询计划,可能会更好。有关如何执行此操作的详细信息,请参阅this answer

    我已经谈到了第三个问题,但是您可以通过手动执行查询来轻松确定查询是否需要调整,例如使用Sql Server Management Studio。如果查询花费很长时间才能完成,即使在重置统计信息后,您可能也需要对其进行调整。为了获得帮助,您应该在新问题中发布确切的查询。

    +27

    我有这个相同的错误,但在一个查询中,'只'花了8secs ......而你关于'exec sp_updatestats'的提示解决了我的问题。非常感谢! – nrod 2013-02-27 12:36:45

    +1

    解决这样的问题几乎从不是调整超时或连接池大小的问题。你需要潜入并找出根本原因。如果您需要帮助解决根本原因,您可以发布自己的问题。 – 2014-07-28 06:36:56

    +3

    这当然不是一个僵局。它可能是由过度的阻塞引起的,但是死锁在一秒钟内解决,并且它们产生不同的错误。这可能是过度阻塞,但不是死锁。 – 2015-03-04 13:53:40

    17

    您可以设置SQL命令的CommandTimeout属性以允许长时间运行的SQL事务。

    您可能还需要查看导致超时的SQL查询。

    +0

    嗨,“或者你需要看看导致超时的SQL查询” - >在SQL Server 2008中,我应该在哪里检查超时? – MoonLight 2011-12-22 10:39:58

    +0

    您可能需要测试从DataLayer.OnlineUsers.Update_SessionEnd_And_Online调用的存储过程,因为堆栈跟踪似乎指向它。将实时数据库的副本带入测试中,如果需要超过30秒才能完成,则运行存储过程传递所需的参数,这就是为什么您要超时。我假设你有权访问SQL Server Management Studio。 – 2011-12-22 10:46:11

    +0

    是的,我有权访问sql server 2008.我应该试试你的方式。 – MoonLight 2011-12-22 11:12:21

    2

    @SilverLight ..这显然是一个数据库对象的问题。它可能是写得不好的查询,或者缺少索引。但截至目前,我不会建议你增加超时不与你的数据库调查发行对象

    NovinMedia.Data.DbObject.RunProcedure(String storedProcName, IDataParameter[] parameters, Int32& rowsAffected) +209 
    

    将断点在此行的代码findout的程序名称,然后通过查看优化程序其执行计划。

    直到您发布有关存储过程的详细信息时,我都无法帮到您。

    +0

    存储过程不会做任何花哨的东西。但是,在执行过程时,似乎OnlineUsers表正被锁定。尝试使用SQL Profiler来查看Application_Start发生了什么 – 2011-12-22 12:00:36

    102

    在您的代码在运行该存储过程,你应该有这样的事情:根据需要

    c.CommandTimeout = 0; 
    

    这将等待多少时间:

    SqlCommand c = new SqlCommand(...) 
    //... 
    

    添加这样一行代码操作完成。

    +105

    您还应该知道0值不是[推荐](http://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqlcommand。 commandtimeout%28v = VS.100%29.aspx):*值为0的指示无限制,并且应避免在CommandTimeout中执行,因为执行命令的尝试将无限期地等待。*最好了解该命令需要多少时间,并在需要时增加超时值。 – Otiel 2013-01-16 12:35:20

    +3

    我同意Otiel并低估了你的回答:当将commandTimeout设置为0时,你不会给Web服务器一个从不响应的数据库服务器恢复的机会。其次,当您触及默认超时时,您应该考虑查看原因。在大多数情况下,修正查询比增加超时时间更好。 – 2015-01-29 08:25:33

    +8

    我不会陷入不推荐它的陷阱。这对我和我的每日计划任务都非常有用:拥有无限超时不会阻止进程完成并在出现问题时返回错误。简而言之,它只是允许您在需要时允许查询完成,而不会在稍后给自己带来麻烦,因为您没有分配足够的时间来完成此过程。您还可以避免通过多线程来锁定程序。 – 2015-07-02 15:57:22

    2

    尝试

    EXEC SP_CONFIGURE 'remote query timeout', 1800 
    reconfigure 
    EXEC sp_configure 
    
    EXEC SP_CONFIGURE 'show advanced options', 1 
    reconfigure 
    EXEC sp_configure 
    
    EXEC SP_CONFIGURE 'remote query timeout', 1800 
    reconfigure 
    EXEC sp_configure 
    

    然后 重建索引

    4

    我最近经过一番简短的调查,发现原因是,我们是在磁盘上运行的空间保存数据库遇到此错误(小于1GB)。

    一旦我将数据库文件(.mdf和.ldf)移出到同一台服务器上的另一个磁盘(具有更多空间),同一页(运行查询)超时装入三秒。

    在尝试解决此错误时,要调查的另一件事是数据库日志文件的大小。您的日志文件可能需要缩小。

    8

    也许它会对某人有用。 我面临同样的问题,在我的情况下,原因是SqlConnection被打开,并没有放置在我调用循环约2500次迭代的方法中。连接池已耗尽。妥善处置解决了这个问题。

    +0

    这个!正是这个。我的问题是我在不等待它们的情况下在不同的线程上触发方法(因为用户不需要该方法的结果,后台脚本)。没有处理(利用'使用'块)我有这个超时问题。这似乎解决了它。 – CularBytes 2015-07-02 16:51:44

    +0

    您是否遇到连接池最大达到或超时过期的超时错误。在操作完成之前超时或服务器没有响应。因为,如果您收到达到的最大池,查看泄漏的连接是有意义的。但是,我得到服务器没有响应错误。 – 2018-02-26 21:07:20

    9

    尽管之前的所有回复都涉及这个问题,但并未涵盖所有情况。

    微软已经承认这个问题,并固定它在2011年支持的操作系统,所以如果你的堆栈跟踪,如:

    Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 
    at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) 
    at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 
    at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error) 
    at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj) 
    

    您可能需要更新您的.NET程序集。

    This issue occurs because of an error in the connection-retry algorithm for mirrored databases.

    When the retry-algorithm is used, the data provider waits for the first read (SniReadSync) call to finish. The call is sent to the back-end computer that is running SQL Server, and the waiting time is calculated by multiplying the connection time-out value by 0.08. However, the data provider incorrectly sets a connection to a doomed state if a response is slow and if the first SniReadSync call is not completed before the waiting time expires.

    参见KB 2605597的详细信息

    https://support.microsoft.com/kb/2605597

    5

    我面临同样的问题,工作就可以了3天左右。我注意到,由于我们的记录数量并不多,我们的高级开发人员在数据库中保留了2张图像和指纹。当我试图获取这个十六进制值需要很长时间时,我计算平均时间来执行我的程序大约38秒。默认的commandtimeout是30秒,因此运行我的存储过程所需时间少于平均时间。我把我的CommandTimeout像下面

    cmd.CommandTimeout = 50 
    

    其工作正常,但有时如果您的查询需要50秒以上,会提示同样的错误。

    1

    我有在sp_foo大的计算是采取大量时间,所以我固定
    这一点点代码

    public partial class FooEntities : DbContext 
    { 
        public FooEntities() 
         : base("name=FooEntities") 
        { 
         this.Configuration.LazyLoadingEnabled = false; 
    
         // Get the ObjectContext related to this DbContext 
         var objectContext = (this as IObjectContextAdapter).ObjectContext; 
    
         // Sets the command timeout for all the commands 
         objectContext.CommandTimeout = 380; 
        } 
    
    3

    你必须设置的CommandTimeout属性问题。您可以在DbContext子类中设置CommandTimeout属性。

    public partial class StudentDatabaseEntities : DbContext 
    { 
        public StudentDatabaseEntities() 
         : base("name=StudentDatabaseEntities") 
        { 
         this.Database.CommandTimeout = 180; 
        } 
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder) 
        { 
         throw new UnintentionalCodeFirstException(); 
        } 
    
        public virtual DbSet<StudentDbTable> StudentDbTables { get; set; } 
    } 
    
    相关问题