У меня есть сервер, на котором размещен мой веб-сайт с почти нулевым трафиком.
Несколько человек (<20) заходят на сайт каждый день, и несколько читателей RSS подписываются на некоторые каналы, которые мы выпускаем. </p>
Почти каждую ночь читатель RSS будет бить нас среди ночи и получит исключение, что веб-сайт не сможет подключиться к SQL Server из-за тайм-аута в соединении.
Детали очень странные, поэтому я ищу некоторую помощь в том, что может быть проблемой, так как я не знаю, с чего начать.
Мы используем ASP.Net MVC, Entity Framework и SQL Server 2008 поверх Windows Server 2008. Машина является выделенной коробкой, которую мы получили от не совсем топ-провайдера, поэтому все может быть настроено неоптимально, или кто знает что еще.
Коробка тоже довольно маленькая, и имеет только 1 Гб оперативной памяти, но она должна принять ту нагрузку, которую мы имеем на данный момент ...
Я копирую полный стек вызовов ниже, но сначала кое-что из того, что мы знаем:
- Ошибка всегда происходит, когда iTunes запрашивает наш сайт. Я считаю, что это не должно иметь ничего общего, но правда в том, что мы получаем это только из iTunes. Мое предположение состоит в том, что это происходит потому, что только iTunes запрашивает нас в то время ночи, когда никто больше не бьет нас.
- Одна из наших теорий состоит в том, что SQL Server и IIS борются за память, и одна из них выгружается на диск из-за неиспользования, и когда кто-то «просыпается», это занимает слишком много времени, чтобы прочитать все с диска обратно в память. Это то, что может произойти? (Я как бы отказываюсь от этого, так как это кажется проблемой дизайна в SQL Server, если бы это было возможно)
- Я также подумал о том, что у нас могут быть утечки соединений, поскольку мы не можем должным образом избавляться от сущностей EF ( см. Мой вопрос здесь ). Это единственное, что я могу найти, прибегнув к помощи проблемы. Я отказываюсь от этого, учитывая крайне низкую нагрузку, которую мы имеем.
- Это всегда происходит ночью, поэтому, скорее всего, это связано с тем, что какое-то время ничего не происходило. Например, я совершенно уверен, что когда эти запросы попадают, процесс веб-сервера перезапускается, и он запускает / повторно JITting все. Однако повторное JITting не объясняет время ожидания SQL.
ОБНОВЛЕНИЕ: Мы прикрепили профилировщик, как это было предложено, и прошло довольно много времени, прежде чем у нас появилось новое исключение. Это новое, что мы знаем:
- С огромным подключением профилировщика уменьшило количество ошибок, которые мы получили. Фактически, после получения нескольких раз в день, мы должны были ждать 3 или 4 дня, чтобы это произошло ОДНАЖДЫ. Как только мы остановили профилировщик, он вернулся к нормальной частоте ошибок (или даже хуже). Таким образом, профилировщик имеет некоторый эффект, который в некоторой степени скрывает эту проблему, но не полностью.
- Если посмотреть трассировку профилировщика рядом с журналом запросов IIS, то между запросами и запросами будет ожидаемое соответствие 1-1. Однако время от времени я вижу МНОЖЕСТВО выполняемых запросов, которые вообще не имеют никакой корреляции с журналом IIS. Фактически, непосредственно перед тем, как фактическая ошибка была зарегистрирована, я получил 750 запросов в течение 3 минут , все из которых были полностью не связаны с журналами IIS. Текст запроса выглядит как нечитаемое дерьмо, которое генерирует EF, и они не все одинаковые, и все они выглядят так же, как запросы, поступающие с веб-сайта: то же имя приложения, пользователь и т. Д. Чтобы понять, насколько это смешно сайт получил около 370 запросов IIS, попавших в БД, в течение 2 дней
- Эти необъяснимые запросы поступили не с того же ClientProcessID, что и предыдущие запросы веб-сайта, хотя, возможно, они все же поступили с веб-сайта, если в то же время процесс был переработан. Между последним объясненным запросом и первым необъяснимым был почти час бездействия.
- Один из этих длинных рядов запросов, которые я не знаю, откуда они пришли, произошел как раз перед тем, как я зарегистрировал ошибку, поэтому я считаю, что это ключ, которому мы должны следовать.
- Как я и ожидал первоначально, когда запрос, выдавший ошибку, был выполнен с другим ClientProcessID, чем предыдущий, (на 8 минут позже, чем предыдущий необъяснимый, и почти ровно на час позже, чем предыдущий IIS). ). Для меня это означает, что рабочий процесс действительно был переработан.
- Это то, чего я абсолютно не понимаю. Журнал IIS показывает, что за одну минуту до запросов об ошибках 4 были полностью обработаны, хотя запросы для них вообще не отображаются в трассировке. На самом деле, после тех 4, которые прошли хорошо, у меня было 4 исключения, выданных в быстрой последовательности, эти 4 ТАКЖЕ не отображаются в трассировке (что имеет смысл, так как, если в соединении был тайм-аут, запрос никогда не должен был выполняться, но я не вижу попыток подключения в трассировке)
Итак, короче говоря, я совершенно не понимаю этого. Я не могу найти причину для тех сотен запросов, которые выполняются в быстрой последовательности, но я считаю, что они должны как-то иметь отношение к проблеме.
Я также не знаю, как диагностировать проблемы с подключением ...
Или как в трассировке Profiler могут отсутствовать некоторые запросы, которые в соответствии с IIS прошли нормально ...
Есть идеи?
Это информация об исключении:
System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
System.Data.EntityException: The underlying provider failed on Open. ---> System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure)
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.FirstOrDefault[TSource](IEnumerable`1 source)
at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__1[TResult](IEnumerable`1 sequence)
at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](Expression expression)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
at MyProject.Controllers.SitesController.Feed(Int32 id) in C:\...\Controller.cs:line 38
at lambda_method(ExecutionScope , ControllerBase , Object[] )
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Любые идеи будут высоко оценены.