Приложение ASP.NET MVC аварийно завершает работу

Я создал приложение MVC 2 для работы в качестве RSS-фидера и доставки содержимого новостей для ряда приложений. Все было хорошо до вчерашнего дня, когда внезапно мое приложение начало выдавать случайную ошибку, которая ничего не говорит мне о том, что происходит (или, по крайней мере, я этого не понимаю). Эта ошибка возникает только в производственной среде и не может быть воспроизведена на промежуточном этапе или на моем локальном компьютере.

Вот трассировка стека:

Ошибка при выполнении дочернего запроса для обработчика System.Web.Mvc.HttpHandlerUtil + ServerExecuteHttpHandlerWrapper. ErrorPath: / Android / Edition / 2011-11-22 / P1 HostIP: ##. ##. ##. ## в System.Web. HttpServerUtility.ExecuteInternal (обработчик IHttpHandler, средство записи TextWriter, логическое значение preserveForm, логическое значение setPreviousPage, путь VirtualPath, путь VirtualPath filePath, String PhysPath, ошибка исключения, String queryStringOverride) в System.Web.HttpServerUtility, писатель BooleanHttpServerUtility (IExe setPreviousPage) в System.Web.HttpServerUtility.Execute (обработчик IHttpHandler, средство записи TextWriter, логическое значение preserveForm) в System.Web.HttpServerUtilityWrapper.Execute (обработчик IHttpHandler, средство записи TextWriterc.Pormage.View, Boolean preserve.Formage.Formage.Formage. viewContext) в System.Web.Mvc.ViewResultBase.ExecuteResult (контекст ControllerContext) в System.Web.Mvc.ControllerActionInvoker. ‹> c_ DisplayClass14.b _11 () в Sys tem.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter (фильтр IResultFilter, преконтекст ResultExecutingContext, продолжение Func1 continuation) at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func1) в System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFiltersc.InvokeActionResultWithFiltersc.InvokeActionResultWithFiltersc.InvokeActionResultWithFiltersc. .WrappedAsyncResult`1.End () в System.Web.Mvc.MvcHandler.EndProcessRequest (IAsyncResult asyncResult) в System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.HttpApplication. (Шаг IExecutionStep, логическое значение и завершено синхронно)

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


person Hallaghan    schedule 30.11.2011    source источник
comment
Вы можете рассказать нам, что такое / Android / Edition / 2011-11-22 / P1?   -  person Francisco    schedule 30.11.2011
comment
/ Android / Edition / 2011-11-22 / P1 - это просто корневой путь, ведущий к действию под названием Edition. Я отображал трассировку стека при возникновении ошибки в этом действии, но он также запускается во всех других действиях.   -  person Hallaghan    schedule 30.11.2011
comment
ММммм, тогда это не актуально. Возможно, эта ссылка может помочь: stackoverflow.com/questions/4862008/   -  person Francisco    schedule 30.11.2011


Ответы (2)


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

Во-первых, вам следует улучшить регистрацию ошибок. В вашем global.asax создайте реализацию ловушки Application_Error, которая регистрирует исключение и все внутренние исключения в файл (я бы не записывал это в базу данных, потому что соединение с базой данных могло быть виновником). Убедитесь, что этот код надежен: он должен фокусироваться на этих критических ошибках, а не регистрировать каждую страницу 404. Кроме того, убедитесь, что сам код ведения журнала не создает никаких проблем (он должен быть очень устойчивым к ошибкам).

Причиной такого рода проблем обычно является доступ к каким-то статическим переменным. Я считаю, что из всех ключевых слов static - безусловно, самое опасное, потому что оно очень тонкое.

Некоторые распространенные ошибки я видел.

  • Кеширование Кто-то хотел проявить смекалку и кэшировать некоторые данные в статическом словаре или около того. К сожалению, код блокировки ошибочен. Исключение возникает только в том случае, если код какого-либо пользователя пытается добавить sth. в кеш, но он там уже есть:

    if(_dict.ContainsKey(cacheKey) == false)
    {
       // second thread adds data to the dictionary here
       _dict.Add(cacheKey, cacheData); // exception
    }
    

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

  • Необычные пути кода Происходит что-то необычное, вызывая код, который не вызывается очень часто, и этот код имеет ошибки. Если у вас есть тестирование с высоким уровнем покрытия кода, проверьте те места, которые не охватываются тестами.

  • Соединение с БД потеряно. Сброс сокета в соединении с БД может привести к исключениям. Многие библиотеки / драйверы для подключения к базе данных исправляют это быстро (т.е. со следующим запросом). С этим трудно справиться; в принципе этого не должно происходить, но есть много причин, по которым это могло произойти.

person mnemosyn    schedule 30.11.2011
comment
Ваш ответ весьма информативен, и я буду исследовать упомянутые вами вопросы. Откровенно говоря, я выполняю кеширование некоторых действий в этом приложении, но это кеширование не используется для действий открытия приложения. Возможно ли, что, когда приложение по какой-то причине вылетает, потребуется время, чтобы возобновить нормальную работу? И чтобы добавить, я использую реализацию Application_Error в global.asax, но я улучшу ее соответственно с вашими советами. Отзыв позже сегодня. - person Hallaghan; 30.11.2011
comment
Хехе, с кешированием, конечно, все в порядке, но легко добавить небольшие ошибки :) Если все приложение должно перезапускаться, возникает большая задержка, потому что представления обычно компилируются на лету. Если это проблема кеширования, возможно, ваш кеш пуст, и теперь все данные должны быть прочитаны снова. Удачи. - person mnemosyn; 30.11.2011
comment
Я каким-то образом заставил его воспроизвести в локальной среде, отправив спам F5 на этой странице, где возникло исключение. Я получил его все еще в отладке и приостановил, пока я исследую переменные. Есть ли у вас какие-нибудь советы, которые я мог бы использовать, чтобы помочь в исследовании этой проблемы? Также, как вы думаете, может ли быть частью этой проблемы тот факт, что я спамил обновление действия? - person Hallaghan; 30.11.2011
comment
да. В производственной среде запросов больше, поэтому высока вероятность того, что два потока будут обращаться к статической переменной одновременно. Обычно этого не происходит при отладке за один сеанс. Если вы продолжите попадать на локальную машину, вы также создадите несколько потоков. Использовать отладчик сложно, потому что он теперь многопоточен, поэтому вы не можете пошагово выполнять свой код. Я бы посоветовал вам включить опцию «прерывание при первой возможности исключения» и попытаться найти ошибку таким образом. - person mnemosyn; 30.11.2011
comment
Я постараюсь включить его и отладить таким образом. Возможно ли, что это исключение вызвано переполнением запроса на это действие? В этом конкретном действии не используются / вызываются статические переменные. Я отвечу тебе, как только найду больше. - person Hallaghan; 30.11.2011
comment
Хм, насколько я знаю, организация очереди запросов обрабатывается на уровне IIS, поэтому она не должна вызывать исключения в вашем коде. Кроме того, эта очередь по умолчанию довольно длинная. Статический доступ может быть скрыт в таких вещах, как доступ к базе данных, доступ к журналу, доступ к некоторым файлам (например, автоматически оптимизированные файлы js / css) и т. Д. - person mnemosyn; 30.11.2011
comment
Что ж, наконец-то я нашла исключение благодаря вашим советам. Это: уже существует открытый DataReader, связанный с этой командой, который необходимо сначала закрыть. Теперь проблема в том, что советы по исправлению этого исключения говорили мне включить MARS на моем connectionString (что я сделал сейчас), но все же, после спама и множества запросов, он в конечном итоге снова взорвался. - person Hallaghan; 30.11.2011
comment
Извините, я не очень часто использую DataReader и не знаю, что такое "MARS". Я предлагаю вам создать новый вопрос для уже известной проблемы; эта ветка комментариев становится слишком длинной. - person mnemosyn; 30.11.2011

Эта ошибка сообщает вам, что настоящая ошибка находится где-то в некотором дочернем действии, то есть действии, отображаемом Html.RenderAction ().

Не существует такой вещи, как «случайная» ошибка - должен быть сценарий, в котором это произойдет, вы просто этого не знаете, потому что условия могут быть разными.

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

person rouen    schedule 30.11.2011
comment
random - это способ назвать его, когда я не уверен, что вызывает эту ошибку, которая, как я уже сказал, действительно происходит для каждого действия любого контроллера в моем приложении. Иногда это может не происходить часами. Стоит упомянуть, что есть страница, которую я загружаю с данными из базы данных, а ответственное действие Action не получает параметров. Так что он загружается всегда одинаково. Это действие иногда вызывает это исключение, а иногда - нет. На самом деле такое случается редко. - person Hallaghan; 30.11.2011
comment
Опять же - ошибка в каком-то дочернем действии, вызываемом Html.RenderAction () из вашего представления или, возможно, даже из макета. Таким образом может показаться, что каждое действие может завершиться сбоем, но это не так - ваше дочернее действие, включенное в результат всех действий, может завершиться сбоем. Изучите действия вашего ребенка. - person rouen; 30.11.2011
comment
Руан, у меня действительно нет дочерних действий, и я даже не знал, что они существуют для MVC2. Любые идеи? - person Hallaghan; 30.11.2011
comment
Я почти уверен, что за этим стоит действие ребенка ... если это не в вашем случае, то я понятия не имею ... - person rouen; 30.11.2011