2009-11-02 2 views
7

У меня есть проект, в котором я нажимаю кучу настраиваемых счетчиков производительности Windows на нескольких серверах и агрегирую их в базу данных. Если сервер не работает, я хочу пропустить его и просто продолжить свой день.Быстрый способ проверить, доступен ли сервер по сети в C#

В настоящее время я проверяю, жив ли сервер, делая DirectoryInfo на общем ресурсе, который я должен посмотреть позже в этом процессе, а затем проверить свойство .Exists.Это мой текущий фрагмент кода для испытания:

DirectoryInfo di = new DirectoryInfo(machine.Share_Path); 
if (!di.Exists) 
{ 
    log.Warn("Could not access " + machine.Name + "! Maybe its down?"); 
    continue; // Skips to the next server in my loop where this snippet exists. 
} 

Это работает, но его довольно медленно. В среднем бит занимает 68 секунд, а бит di.Exists заканчивается, и я в идеале должен знать через секунду, доступен ли сервер. Pinging также не является вариантом, поскольку сервер может быть pingable, но не «жить» в нашей среде.

Я все еще немного свежий для мира .NET, поэтому я открыт для любых советов, которые могут предложить люди.

Заранее спасибо.

-Weegee

+0

Нужно ли 68 секунд, когда сервер находится там, когда сервера нет, или и то, и другое? –

+0

Когда сервера нет. Когда сервер там, он занимает меньше секунды. – Weegee

+0

Как насчет запуска проверки в отдельном рабочем потоке и просто позволяя ему взять, сколько нужно времени? – Dolphin

ответ

8

Ping Во-первых, потом задавать вопросы

Почему не пинг первый, а затем сделать di.Exists, если вы получите ответ?

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

У меня, по сути, этот метод успешно использовался раньше.


Paralellize

Другой вариант вы имеете в paralellize проверку, и действия на серверах, поскольку они, как известно, должны быть доступны.

Вы можете использовать метод Paralell.ForEach() и использовать потокобезопасную очередь вместе с простым потребительским потоком для выполнения требуемого действия. В сочетании с вышеописанным методом проверки это может облегчить почти все ваши узкие места при проверке вверх/вниз.


стук в дверь

Еще один метод будет ckeck если требуется удаленный сервис работает (либо путем нажатия клавиши свой порт непосредственно или запрашивая его с WMI).

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

+0

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

+1

Hrm ... Есть ли удаленный сервис, который вы можете проверить на машине? Или использовать удаленный WMI? –

+0

Удаленный WMI - отличная идея. Я уже пытаюсь поразить некоторые счетчики Perf, поэтому я просто попробую создать фиктивный, который, как я знаю, существует на каждом сервере (% Processor Time \ _Total), и если он терпит неудачу, я пропущу этот сервер.Не знаю, почему я об этом не думал раньше. Еще раз спасибо! – Weegee

2

Единственный «быстрый» способ, по-моему, проверить, не работает ли он, опираясь на ping, - это создать сокет и посмотреть, действительно ли вы можете подключиться к порту службы, которую вы пытаетесь достичь.

Это будет эквивалент telnet servername 135, чтобы узнать, все ли это.

В частности ...

  1. Создание клиента .NET TCP сокетов (System.Net.Sockets.TcpClient)
  2. Вызов BeginConnect() в качестве асинхронной операции, чтобы подключиться к серверу в вопрос на одном из портов RPC, что ваш код существует в любом случае (TCP 135, 139 или 445).
  3. Если вы не слышите от него в течение X миллисекунд, позвоните Close(), чтобы отменить соединение.

Отказ от ответственности: Я понятия не имею, какой эффект это будет иметь на какой-либо защиты/брандмауэра угроз, которые могут видеть этот тип Connect/Disconnect без каких-либо данных, посылаемых деятельность как угрозу.

0
  • «полномасштабный» вариант будет установить инструмент мониторинга, как SCOM (System Center Operations Manager), это имеет SDK вы можете использовать для запроса SCOM для (производительность) и информация о техническом обслуживании AVOUT машин является мониторинг. Мог быть мостом к далеко, хотя ....

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

  • Создайте небольшую службу Windows, что вы устанавливаете на вашей целевой машине, есть системный администратор остановить его, когда они выполняют обслуживание на целевой машине (просто использовать пакетный файл для чистой остановки/чистой запуска службы)

1

Открытие разъема на конкретный порт обычно делает трюк. Если вы действительно хотите, чтобы это было быстро, обязательно установите свойство NoDelay в новом сокете (алгоритм Nagle), чтобы не было буферизации.

Быстрое будет во многом зависеть от латентности, но это, вероятно, самый быстрый способ связи с конечной точкой. Это довольно просто распараллеливать, используя методы async. Как быстро вы можете проверить, во многом будет зависеть от вашей топологии сети, но в тестах на 1000 серверов (латентность между 0-75 мс) я смог получить состояние подключения через ~ 30 секунд. Не научные данные вообще, а должны дать вам эту идею.

Кроме того, никогда не делайте этого через общие папки UNC, потому что, если сервер больше не существует, у вас будет много висячих подключений, которые навсегда переходят к таймауту. Поэтому, если у вас много серверов с недопустимыми записями DNS, и вы пытаетесь опросить их, вы полностью потеряете Windows. Такие вещи, как File.Exists и любой доступ к файлам, вызовут это.

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