2011-12-22 3 views
210

У меня есть много пользователей на моем веб-сайте (20000-60000 в день), который является сайтом загрузки для мобильных файлов. У меня есть удаленный доступ к моему серверу (сервер Windows 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


EDIT ПОСЛЕ ОТВЕТЫ: ​​
мой Application_Start в Global.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 

У меня есть два метода для получения онлайн-пользователей:

  1. с использованием Application["OnlineUsers"] = 0;
  2. другой, используя базу данных

Так, для метода # 2 Я сброс всех OnlineUsers на Application_Start. В этой таблице содержится более 482 751 записей.

+0

Как говорится здесь [по умолчанию 15 секунд] (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectiontimeout.aspx) – V4Vendetta

+0

Лучше сделать корень анализ причин, Существуют различные причины, вызывающие такую ​​проблему. Основная часть - сложная структура запроса. Я столкнулся с такой же проблемой, когда получаю изображения, которые хранятся как значения Hex в таблице. –

+0

Помимо приведенных выше причин, я добавлю еще один: Тайм-аут блокировки: https://docs.microsoft.com/en-us/sql/t-sql/statements/set-lock-timeout-transact-sql Если это нить, ожидающая блокировки слишком долго, это будет тайм-аут, основанный на вышеуказанном документе. –

ответ

249

Похоже, у вас есть запрос, который занимает больше времени, чем нужно. Из вашей трассировки стека и кода вы сможете точно определить, что такое запрос.

Этот тип таймаута может иметь три причины;

  1. Там в тупик где
  2. статистики и/или план запроса кэша базе данных неверны
  3. Запрос слишком сложен и должен быть настроен

Тупик может быть трудно исправить , но легко определить, так ли это. Подключитесь к своей базе данных с помощью Sql Server Management Studio. В левой панели щелкните правой кнопкой мыши узел сервера и выберите Activity Monitor. Взгляните на запущенные процессы. Обычно большинство из них будут простаивать или работать. Когда проблема возникает, вы можете идентифицировать любой заблокированный процесс по состоянию процесса. Если вы щелкните правой кнопкой мыши процесс и выберите , то детали покажет вам последний запрос, выполненный процессом.

Вторая проблема заставит базу данных использовать неоптимальный план запроса. Она может быть решена путем очистки статистики:

exec sp_updatestats 

Если это не работает, вы можете попробовать

dbcc freeproccache 

Вы не должны делать это, когда ваш сервер находится под большой нагрузкой, поскольку он будет временно нести большая производительность, так как все сохраненные procs и запросы перекомпилируются при первом выполнении. Однако, поскольку вы указываете, что проблема возникает иногда, а трассировка стека указывает, что ваше приложение запускается, я думаю, что вы выполняете запрос, который выполняется только иногда. Возможно, вам будет лучше, если SQL Server не будет повторно использовать предыдущий план запроса. См. this answer для получения подробной информации о том, как это сделать.

Я уже затронул третью проблему, но вы можете легко определить, нуждается ли запрос в настройке, выполнив запрос вручную, например, используя Sql Server Management Studio. Если запрос занимает слишком много времени, даже после сброса статистики вам, вероятно, потребуется настроить его. Для этого вам следует отправить точный запрос в новый вопрос.

+27

У меня была такая же ошибка, но в запросе, «просто» заняло 8 секунд ... и ваш отзыв о 'exec sp_updatestats' решил мою проблему. Большое спасибо! – nrod

+1

Решение такой проблемы почти никогда не зависит от тайм-аутов настройки или размера пула соединений. Вам нужно будет погрузиться и выяснить основную причину. Если вам нужна помощь в разрешении этой основной причины, вы можете опубликовать свой собственный вопрос. –

+3

Это, безусловно, не тупик. Это может быть вызвано чрезмерной блокировкой, но взаимоблокировки разрешаются за секунду, и они генерируют разные ошибки. Это может быть чрезмерная блокировка, но не блокировка. –

17

Вы можете установить свойство SQL-команды CommandTimeout, чтобы разрешить длительную транзакцию SQL.

Возможно, вам также потребуется посмотреть SQL-запрос, вызывающий таймаут.

+0

привет, "или вам нужно посмотреть SQL-запрос, вызывающий таймаут" -> в SQL Server 2008, где я должен проверить этот тайм-аут? – MoonLight

+0

Возможно, вам придется протестировать хранимую процедуру, вызванную из DataLayer.OnlineUsers.Update_SessionEnd_And_Online, поскольку трассировка стека, похоже, указывает на нее. Возьмите копию живой базы данных в тест и запустите процесс Хранимой процедуры в требуемых параметрах, если для завершения потребуется более 30 секунд, поэтому вы получаете тайм-аут. Я предполагаю, что у вас есть доступ к SQL Server Management Studio. –

+0

да, у меня есть доступ к SQL Server 2008. Я должен попробовать. – MoonLight

2

@SilverLight .. Это явно проблема с объектом базы данных. Это может быть плохо написанный запрос или отсутствующие индексы. Но сейчас я не предлагаю вам увеличить время ожидания без изучения проблемы с базой данных объектов

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

Поставьте точку останова на этой строке кода, чтобы Findout имя процедуры, а затем оптимизировать процедуру, глядя на его план выполнения.

Я не могу больше помочь вам до тех пор, пока вы не разместите данные о хранимой процедуре.

+0

Сохраненная процедура не имеет ничего общего. Однако похоже, что таблица OnlineUsers блокируется во время выполнения процедуры. Попробуйте профилировщик SQL, чтобы узнать, что происходит на Application_Start –

102

В своем коде, где запустить хранимую процедуру, вы должны иметь что-то вроде этого:

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

Добавить такую ​​строку кода:

c.CommandTimeout = 0; 

Это будет ждать столько времени, сколько необходимо для завершение операции.

+105

. Вы также должны знать, что значение 0 не [рекомендуется] (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand. commandtimeout% 28v = VS.100% 29.aspx): * Значение 0 указаний без ограничений, и его следует избегать в CommandTimeout, потому что попытка выполнить команду будет ждать бесконечно.* Лучше узнать, сколько времени занимает команда, и при необходимости увеличить значение таймаута. – Otiel

+3

Я согласен с Otiel и отклонил ваш ответ: при настройке commandTimeout на 0 вы не даете веб-серверу возможности восстановления с сервера базы данных, который не отвечает. Во-вторых, когда вы нажимаете на тайм-аут по умолчанию, вам следует рассмотреть вопрос о причине. В большинстве случаев лучше исправить запрос, чем увеличить время ожидания. –

+8

Я бы не попал в ловушку, не рекомендуя это. Это было очень полезно для меня и моих ежедневных запланированных задач: наличие бесконечного тайм-аута не останавливает процесс, завершающий и возвращающий ошибку, если что-то пойдет не так. Проще говоря, это просто позволит вам разрешить завершение запроса, когда это необходимо, без проблем позже, потому что вы не выделили достаточно времени для завершения процесса. Вы также можете избежать блокировки вашей программы с помощью многопоточности. –

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

я встретил эту ошибку недавно, и после некоторого короткого расследования, нашли причину, чтобы быть, что мы выбегали пространства на диске держит базу данных (менее 1 ГБ).

Как только я вытащил файлы базы данных (.mdf и .ldf) на другой диск на том же сервере (с большим количеством места), на той же странице (выполняющей запрос), которая была рассчитана на время в течение трех секунд.

Еще одна вещь, которую нужно исследовать при попытке решить эту ошибку, - это размер файлов журнала базы данных. Возможно, ваши файлы журналов должны быть сокращены.

8

Возможно, это будет полезно для кого-то. Я столкнулся с той же проблемой, и в моем случае причина заключалась в том, что SqlConnection был открыт и не был удален в методе, который я вызывал в цикле с примерно 2500 итерациями. Пул соединений был исчерпан. Правильное распоряжение решило проблему.

+0

это! именно это. Моя проблема заключалась в том, что я запускал методы в другом потоке, не дожидаясь их (потому что пользователю не нужен результат этого метода, фоновый скрипт). Без утилизации (используя блоки 'using') у меня есть эта проблема с таймаутом. Казалось, это решило. – CularBytes

+0

Вы получили ошибку таймаута с достигнутым пулом подключений или таймаутом. Период ожидания истекает до завершения операции или сервер не отвечает. Поскольку, если вы получаете максимальный пул, то имеет смысл изучить просочившееся соединение. но я получаю сообщение об ошибке сервера. –

9

Хотя все более ранние ответы затрагивают проблему, они не охватывают все случаи.

Microsoft признала эту проблему и установил его в 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 изображения и Fingerprint в базе данных. Когда я пытаюсь извлечь эти шестнадцатеричные значения, это занимает много времени, я рассчитываю среднее время для выполнения моей процедуры около 38 секунд. По умолчанию время командной строки составляет 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. Вы можете установить атрибут CommandTimeout в дочернем классе DbContext.

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; } 
} 
Смежные вопросы

 Смежные вопросы