Указанная выше ошибка также может возникать в журналах приложений при использовании счетчиков производительности WCF на основе процесса . Признаки этого - блок из трех ошибок в журналах событий приложения:
Счетчик производительности не загружен.
Название категории: ServiceModelService 3.0.0.0
Имя счетчика: звонки
Исключение: System.InvalidOperationException: Экземпляр abc@def|service.svc уже существует с жизненным циклом процесса. Он не может быть воссоздан или использован повторно до тех пор, пока он не будет удален или пока процесс, использующий его, не завершится.
Это всегда происходит сразу после следующего информационного сообщения в журналах системных событий:
Рабочий процесс с идентификатором процесса «nnnn», обслуживающего пул приложений «MyAppPool», запросил перезапуск, поскольку рабочий процесс достиг допустимого времени обработки.
Это приводит к тому, что счетчики монитора производительности для этой службы становятся недоступными, по-видимому, в течение нескольких часов.
Номер версии ServiceModelService 3.0.0.0
будет зависеть от версии .NET, которую вы используете (это было проверено с использованием .NET 3.5).
* * Фон тысяча двадцать-один * * тысяча двадцать-дв
Ошибка вызвана тем, что рабочий процесс достигает своего предела времени обработки, после чего он должен быть переработан. Это задается в параметрах перезапуска пула приложений IIS (IIS 6.0 и выше, поэтому Windows Server 2003 и выше). Переработка рабочего процесса приводит к конфликту имени счетчика производительности на основе нового процесса со старым, что приводит к ошибке. Это связано с тем, что в IIS используется переопределенная переработка , где рабочий процесс, который должен быть завершен, продолжает работать до тех пор, пока не будет запущен новый рабочий процесс.
Воспроизведение
(протестировано на Windows Server 2003 = IIS 6.0)
- Создание службы WCF.
- Добавьте следующие к
web.config
в разделе <system.serviceModel>
:
<diagnostics performanceCounters="All" />
- В свойствах пула приложений для службы в разделе Свойства → Переработка установите рабочий процесс Перезапуск на 1 минуту. Ручная переработка пула приложений не имеет никакого эффекта, поскольку это не создает запроса от рабочего процесса на повторную обработку (как видно из журналов системы просмотра событий с
W3SVC
информационными событиями).
- В soapUI создайте набор тестов / тестовый набор / шаг теста / запрос теста для операции WCF.
- Добавьте тестовый пример либо к нагрузочному тесту в soapUI, либо используйте loadUI , вызывая вызов со скоростью 1 в секунду.
- Каждую 1 минуту рабочий процесс будет запрашивать перезапуск (это видно из системных журналов). Каждые 2 минуты это приводит к пакету из трех ошибок в журналах приложений от
System.ServiceModel 3.0.0.0
.
- Счетчики производительности для этой службы будут недоступны до тех пор, пока рабочий процесс снова не перезагрузится. (Обратите внимание, что на этом этапе для периода повторного использования устанавливается более высокое значение, чтобы узнать, как долго счетчики производительности недоступны, фактически перезапустят процессы и снова сделают счетчики доступными.)
Возможные решения
Решение 1 - красная сельдь
Исправление KB981574 заменяет исправление KB971601 . Последнее исправление описывает проблему:
ИСПРАВЛЕНИЕ: счетчики производительности, которые отслеживают приложение, перестают отвечать при его выходе и перезапуске, и вы получаете исключение System.InvalidOperationException на компьютере под управлением .NET Framework 2.0
Применение прежнего исправления не устраняет проблему. Применение последнего исправления вызвало ошибки пула приложений.
Решение 2 - рабочий раствор
Можно создать фабрику хостов службы, которая предоставляет настраиваемый хост службы :
using System;
using System.Diagnostics;
using System.ServiceModel;
using System.ServiceModel.Activation;
namespace MyNamespace
{
public class WebFarmServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(
Type serviceType, Uri[] baseAddresses)
{
return new WebFarmServiceHost(serviceType, baseAddresses);
}
}
public class WebFarmServiceHost : ServiceHost
{
public WebFarmServiceHost(
Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses) { }
protected override void ApplyConfiguration()
{
base.ApplyConfiguration();
Description.Name = "W3wp" + Process.GetCurrentProcess().Id +
Description.Name;
}
}
}
И обратиться к фабрике в сервисной разметке .svc
Файл:
<%@ ServiceHost Language="C#" Debug="true" Factory="MyNamespace.WebFarmServiceHostFactory" Service="WcfService1.Service1" CodeBehind="Service1.svc.cs" %>
Финальные настройки
К сожалению, хотя из-за этого проблема возникает гораздо реже, она все же возникает (примерно в 30 раз меньше, хотя я не измерил точную статистику по этому вопросу).
Простая настройка, которая, похоже, полностью решает проблему, заключается в добавлении команды режима сна непосредственно перед base.ApplyConfiguration();
:
Thread.Sleep(1);
Это срабатывает только один раз за цикл рабочего процесса, поэтому должно оказывать незначительное влияние на производительность службы. Возможно, вам придется повысить это значение (вы можете сделать его настраиваемым), хотя минимальная настройка в 1 мс сработала для меня (спор о том, как долго эта команда фактически спит в стороне).
Решение 3 - самое простое исправление
В IIS есть DisallowOverlappingRotation
свойство метабазы . Этот может быть установлен следующим образом (пример приведен для MyAppPool
пула приложений):
cscript %SYSTEMDRIVE%\inetpub\adminscripts\adsutil.vbs SET w3svc/AppPools/MyAppPool/DisallowOverlappingRotation TRUE
Сравнение решений
Решение № 3 приведет к тому, что ваш сайт будет дольше не работать , когда рабочий процесс перезапустится из-за отсутствия повторного использования IIS.
В ходе тестов нагрузки WUU основного базового веб-сервиса, использующих более 100 транзакций в секунду с 5 потоками, «зависание», когда новые транзакции блокировались, проявлялось в течение нескольких секунд каждый раз, когда рабочий процесс перерабатывался. Это зависание было более продолжительным (8+ секунд) при тестировании более сложного веб-сервиса.
Решение № 2 не создавало такой блокировки, имело плавный поток ответов во время повторного цикла и не приводило к ошибкам конфликта пермонов.
Заключение
Для веб-сервисов, где низкая задержка не является обязательным, можно использовать решение № 3. Вы даже можете установить ежедневную переработку в определенное время, если знаете распределение нагрузки и тихое время суток (это можно сделать на той же вкладке в IIS). Это даже может быть поражено, если используется веб-ферма.
Для веб-сервисов, которые не могут терпеть такие задержки, решение №2 является наилучшим способом продвижения вперед.