我的网站有很多用户(每天2万到6万),这是一个移动文件下载网站。我可以远程访问我的服务器(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


回答后编辑: my Application_Start在全局。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

我有两种获取在线用户的方法:

using Application["OnlineUsers"] = 0; 另一个使用数据库

因此,对于方法#2,我重置所有在线用户在Application_Start。该表中有超过482,751条记录。


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

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


@SilverLight . .这显然是数据库对象的一个问题。它可能是一个写得很糟糕的查询,或者缺少索引。但到目前为止,我不会建议您在不调查数据库对象的问题之前增加超时时间

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

在这行代码上放置一个断点,以找出过程名称,然后通过查看过程的执行计划来优化过程。

在您发布有关存储过程的详细信息之前,我无法提供更多帮助。


在你运行存储过程的代码中,你应该有这样的东西:

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

添加这样一行代码:

c.CommandTimeout = 0;

这将等待操作完成所需的时间。


看起来您的查询花费的时间比它应该花费的时间要长。 从堆栈跟踪和代码中,您应该能够准确地确定该查询是什么。

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

在某个地方出现了僵局 数据库的统计信息和/或查询计划缓存不正确 查询太复杂,需要调优

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

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

exec sp_updatestats

如果这行不通,你也可以试试

dbcc freeproccache

当您的服务器负载过重时,您不应该这样做,因为当第一次执行时,所有存储的procs和查询都会重新编译,这会暂时导致很大的性能损失。 但是,由于您指出问题有时会发生,并且堆栈跟踪指示应用程序正在启动,因此我认为您正在运行一个仅偶尔运行的查询。强制SQL Server不重用以前的查询计划可能会更好。有关如何做到这一点的详细信息,请参阅这个答案。

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


try

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

然后 重新构建索引


我最近遇到了这个错误,经过简单的调查后,发现原因是存储数据库的磁盘空间不足(小于1GB)。

当我移出数据库文件(。MDF和.ldf)到同一服务器上的另一个磁盘(有更多的空间),同一页面(运行查询)在3秒内超时加载。

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


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


虽然所有早期的答复都涉及这一问题,但并没有涵盖所有情况。

微软已经承认了这个问题,并在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


我遇到了同样的问题,花了大约3天时间。我注意到,由于我们的记录数量不多,我们的高级开发人员在数据库中保留了2张图像和指纹。当我试图获取这个十六进制值,它需要很长时间,我计算平均时间来执行我的程序大约38秒。默认的命令超时是30秒,因此它小于运行存储过程所需的平均时间。我像下面这样设置我的命令超时

cmd.CommandTimeout = 50

它的工作很好,但有时如果你的查询超过50秒,它会提示同样的错误。


我在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;
    }

您必须设置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; }
}

默认超时时间是15秒,要改变它,0是无限的,任何其他数字是秒数。

在代码中

using (SqlCommand sqlCmd = new SqlCommand(sqlQueryString, sqlConnection))
   {
      sqlCmd.CommandTimeout = 0; // 0 = give it as much time as it needs to complete
      ...
    }

在你的网里。配置,“命令超时=0;”不超时,或低于1小时(3600秒)

  <add name="ConnectionString" connectionString="Data Source=ServerName;User ID=UserName;Password=Password;Command Timeout=3600;" providerName="System.Data.SqlClient" />

超时,因为sql查询花费的时间超过了您设置的时间 在sqlCommand。CommandTimeout财产。 显然,您可以增加CommandTimeout来解决这个问题,但是 在此之前,您必须通过添加索引来优化查询。如果你 运行您的查询在Sql server管理工作室,包括实际 执行计划,然后Sql server管理工作室将建议 你适当的索引。大多数情况下,您将摆脱超时问题 如果你能优化你的查询。


TLDR:

在数据量、网络设置和代码没有改变的情况下,重新启动应用程序和DB服务器是最快的修复方法。我们一向是这样做的 可能是指示失败的硬盘驱动器,需要更换检查系统通知


我经常因为各种原因遇到这个错误,并有各种解决方案,包括:

refactoring my code to use SqlBulkCopy increasing Timeout values, as stated in various answers or checking for underlying causes (may not be data related) Connection Timeout (Default 15s) - How long it takes to wait for a connection to be established with the SQL server before terminating - TCP/PORT related - can go through a troubleshooting checklist (very handy MSDN article) Command Timeout (Default 30s) - How long it takes to wait for the execution of a query - Query execution/network traffic related - also has a troubleshooting process (another very handy MSDN article) Rebooting of the server(s) - both application & DB Server (if separate) - where code and data haven't changed, environment must have changed - First thing you must do. Typically caused by patches (operating system, .Net Framework or SQL Server patches or updates). Particularly if timeout exception appears as below (even if we do not use Azure): System.Data.Entity.Core.EntityException: An exception has been raised that is likely due to a transient failure. If you are connecting to a SQL Azure database consider using SqlAzureExecutionStrategy. ---> System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The semaphore timeout period has expired.) ---> System.ComponentModel.Win32Exception: The semaphore timeout period has expired


还要确保没有待处理的事务。:)

我做了一些测试,开始了一个交易以确保安全,但从未关闭它。我希望错误会更明确,但哦,好吧!


我们在超时过期/最大池达到Sqlexception时遇到了困难。为了避免重新启动服务器或服务,我们修改SQL server中的MAX server MEMORY变量(通过SQL management Studio或T-SQL):

DECLARE @maxMem INT = 3000 --Max. memory for SQL Server instance in MB
EXEC sp_configure 'show advanced options', 1
RECONFIGURE

这将暂时修复问题,直到再次发生。在我们的例子中,我们怀疑这与应用程序级别的连接泄漏有关。


我们最近升级到NuGet版本的SqlClient (Microsoft.Data.SqlClient),其中包含一个错误。此错误是在1的生命周期中引入的。X周期,已经固定。该修复将在2.0.0版本中可用,但在撰写本文时还不可用。可以预览一下。

你可以在这里查看详细信息: https://github.com/dotnet/SqlClient/issues/262


如果您正在使用ASP。使用Startup.cs约定,你可以像这样访问和设置查询命令超时选项:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContextPool<MyDbContext>(_ =>
    {
        _.UseSqlServer(Configuration.GetConnectionString("MyConnectionString"), options => 
        {
            options.CommandTimeout(180); // 3 minutes
        });
    });
}

我也有同样的问题,并通过在web中添加“连接时间”值来解决。配置文件。找到connectionStrings并添加连接超时=3600"

这是样本

  <connectionStrings>
    <add name="MyConn" providerName="System.Data.SqlClient" connectionString="Data Source=MySQLServer;Initial Catalog=MyDB;User ID=sa;Password=123;Connection Timeout=3600" />
  </connectionStrings>

此外,您还需要检查单个记录是否没有在逻辑中得到更新,因为在该位置使用更新触发器也会导致超时错误。

因此,解决方案是确保在循环/游标之后执行批量更新,而不是在循环中一次执行一条记录。


我有这个问题,但当我离开ADO后,它就消失了。Net到Dapper为我的查询。


我曾经遇到过这个问题,在我的情况下是一个未提交的SQL事务。在我投入之后,问题就消失了。


正如其他人所说,这个问题可能与悬而未决的事务有关。 在我的例子中,我必须将DbTransaction变量作为ExecuteScalar方法中的参数发送,以便正确地执行过程。

之前:

ExecuteScalar(command)

后:

ExecuteScalar(command, transaction)

在我的例子中,我使用了EntityFrameworkCore。 由于我想处理的输入超过了查询限制,这个错误来找我。 我的案例的解决方案是将数据处理分割成块,通过这种方法,我能够适应限制。 是的,这需要时间,但至少它处理了所有的输入记录。


我在我的多线程程序上得到了同样的错误,有超过2000个用户同时连接。当我运行一个超过5000行的SELECT命令时,问题发生了。该命令被插入命令阻止。通过将SELECT *更改为SELECT Top(n) *, n<5000即可修复