На моей работе у меня есть набор из шести служб Windows, за которые я отвечаю, написанных на C # 2003. Каждая из этих служб содержит таймер, который срабатывает каждую минуту или около того, где происходит большая часть их работы.
Моя проблема в том, что при запуске этих сервисов они начинают потреблять все больше и больше процессорного времени на каждой итерации цикла, даже если для них не требуется какой-либо значимой работы (т. Е. Они просто простаивают, ищут через базу данных что то сделать). При запуске каждая служба использует в среднем (около) 2-3% из 4 процессоров, что вполне нормально. Через 24 часа каждая служба будет использовать весь процессор в течение всего цикла работы.
Кто-нибудь может помочь? Я в недоумении относительно того, что может быть причиной этого. Наше текущее решение состоит в том, чтобы перезапускать службы один раз в день (они отключаются, затем сценарий видит, что они отключены, и перезапускает их примерно в 3 часа ночи). Но это не долгосрочное решение; Меня беспокоит то, что по мере того, как сервисы становятся более загруженными, их перезапуск один раз в день может оказаться недостаточным ... но поскольку существует значительный штраф при запуске (все они используют NHibernate для доступа к данным), так как они становятся более занятыми, именно это мы не хочет делать это перезапускать их чаще.
@ akmad: Правда, это очень сложно.
- Да, служба, запущенная в изоляции, с течением времени будет показывать один и тот же симптом.
- Нет, это не так. Мы смотрели на это. Это может произойти в 10 утра или 6 вечера или в середине ночи. Там нет последовательности.
- Мы делаем; и они. Службы делают именно то, что они должны быть, и ничего больше.
- К сожалению, для этого необходимо заранее знать, когда именно сервисы будут максимально загружать процессоры, что происходит по непредсказуемому графику и никогда не очень быстро ... что усложняет ситуацию вдвойне, потому что мой начальник будет запускать и перезапускать их, когда у них возникают проблемы, не думая о проблемах отладки.
- Нет, они используют достаточно постоянный объем ОЗУ (около 60-80 МБ каждый, из 4 ГБ на машине).
Хорошие предложения, но будьте уверены, мы попробовали все обычные способы устранения неполадок. Я надеюсь, что это проблема .NET, о которой кто-то может знать, и которую мы можем решить. Решение моего босса (которое я категорически не хочу реализовывать) состоит в том, чтобы поместить в базу данных поле, в котором несколько раз можно перезапустить службы в течение дня, чтобы он мог устранить проблему и не думать об этом. , Я отчаянно ищу причину настоящей проблемы, чтобы исправить ее, потому что это решение станет катастрофой примерно через шесть месяцев.
@ Яаков Эллис: У каждого из них своя функция. Один читает записи из базы данных Oracle где-то вне сайта; другой обрабатывает эти записи и передает файлы, принадлежащие этим записям, в нашу систему; третий проверяет эти файлы, чтобы убедиться, что они такие, какими мы их ожидаем; другая - сервисная служба, которая постоянно проверяет такие вещи, как дисковое пространство (которого у нас достаточно) и опрашивает другие серверы, чтобы убедиться, что они живы; один из них работает только для того, чтобы убедиться, что все остальные работают и выполняют свою работу, отслеживает и сообщает об ошибках, а также перезапускает все, что не может обеспечить работу всей системы 24 часа в сутки.
Итак, если вы спрашиваете, что я думаю, вы спрашиваете, нет, нет ни одной общей вещи, которую делают все эти службы (кроме доступа к базе данных через NHibernate), которую я могу указать как потенциальную проблему. К сожалению, если это окажется реальной проблемой (что меня не сильно удивит), все это может быть испорчено - и я закончу переписывать их все на простой SQL. Я надеюсь, что это проблема сборщика мусора или что-то более простое, чем NHibernate.
@ Джошдан: Не секрет. Как я уже сказал, мы попробовали все обычные способы устранения неполадок. Профилирование не помогло: используемый нами профилировщик не смог указать ни на какой код, который фактически выполнялся при высокой загрузке ЦП. Эти службы были разорваны около месяца назад в поисках этой проблемы. Каждый раздел кода был проанализирован, чтобы попытаться выяснить, был ли наш код проблемой; Я здесь не спрашиваю, потому что я не сделал свою домашнюю работу. Если бы это был простой случай, когда сервисы выполняли больше работы, чем предполагалось, это было бы замечено.
Проблема в том, что в большинстве случаев сервисы вообще ничего не делают, но все же им удается потреблять 25% или более из четырех процессорных ядер: они не находят работы и выходят из цикла и ждем следующей итерации. Это, в буквальном смысле, почти не требует времени процессора.
Вот пример поведения, которое мы наблюдаем в службе без работы в течение двух дней (в неизменной среде). Это было снято на прошлой неделе:
День 1, 8 утра: ср. Загрузка процессора примерно 3%
День 1, 6 вечера: ср. Загрузка процессора около 8%
День 2, 7 утра: ср. Загрузка процессора около 20%
День 2, 11 утра: ср. Загрузка процессора около 30%
Рассмотрев все возможные обыденные причины этого, я задал этот вопрос здесь, потому что решил (справедливо, как выясняется), что получу более инновационные ответы (например, Убигути) или указатели на вещи Я не думал (как предложение Иана).
Так происходит ли скачок процессора?
непосредственно перед таймером
обратный вызов, внутри обратного вызова таймера,
или сразу после таймера
Обратный вызов
Вы неправильно поняли. Это не спайк. Если бы это было, не было бы никаких проблем; Я могу справиться с шипами. Но это не так ... Загрузка процессора в целом возрастает. Даже когда служба ничего не делает, ждет следующего нажатия таймера. Когда служба запускается, все хорошо и спокойно, а график выглядит так, как вы ожидаете ... как правило, 0% использования, с скачками до 10%, когда NHibernate попадает в базу данных, или служба выполняет какой-то тривиальный объем работы , Но это увеличивает общее использование на 25% (больше, если я позволю этому зайти слишком далеко) во время работы процесса.
Это сделало предложение Яна логической серебряной пулей (NHibernate делает много вещей, когда вы не смотрите). Увы, я реализовал его решение, но оно не дало эффекта (у меня нет никаких доказательств этого, но я на самом деле думаю, что это ухудшило ситуацию ... Среднее использование , кажется, , чтобы подняться значительно быстрее сейчас). Обратите внимание, что удаление «разделов» NHibernate (как вы рекомендуете) неосуществимо, поскольку это приведет к удалению около 90% кода в сервисе, что позволит мне исключить таймер как проблему (что я абсолютно намереваюсь попробуйте), но я не могу помочь исключить NHibernate как проблему, потому что если NHibernate вызывает эту проблему, то внедренное хитрое исправление (см. ниже) просто должно стать The Way The System Works; Мы настолько зависим от NHibernate для этого проекта, что премьер-министр просто не примет, что он вызывает неразрешимую структурную проблему.
Я только что заметил чувство отчаяния в
вопрос - это твои проблемы
будет продолжать, если не будет маленького чуда
Не имею в виду, что это так оторвется. В данный момент сервисы перезапускаются ежедневно (с возможностью ввода любого количества часов в день, чтобы они могли их выключить и перезапустить), что исправляет проблему, но не может быть долгосрочным решением, когда они выходят на рабочий компьютер. и начать становиться занятым. Проблемы не будут продолжаться, буду ли я их исправлять, или премьер-министр поддерживает это ограничение на них. Очевидно, что я бы предпочел реализовать реальное исправление, но поскольку первоначальное тестирование не выявило причин для этого, а сервисы уже были тщательно проанализированы, администратор предпочел бы просто перезапустить их несколько раз, а не тратить больше времени на их устранение. , Это полностью вне моего контроля и делает чудо, о котором вы говорили, более важным, чем могло бы быть.
Это очень интригующе (насколько
как вы доверяете своему профилировщику).
Не знаю. Но тогда это службы Windows, написанные на .NET 1.1, работающие на компьютере под управлением Windows 2000, развернутые с помощью хитроумного сценария Нанта, использующего старую версию NHibernate для доступа к базе данных. На этой машине мало что, на самом деле, я бы сказал, что доверяю.