Мониторинг порта TCP - PullRequest
3 голосов
/ 21 апреля 2009

Ради интереса, я возился с написанием балансировщика нагрузки на python и пытался найти лучший (правильный?) Способ проверить, доступен ли порт и удаленный хост все еще там.

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

Когда я использую неблокирующие сокеты, я заметил, что recv () вернет ошибку («ресурс временно недоступен»), когда он читает из живого сокета, но возвращает «» при чтении из мертвого (отправить и recv 0 байтов, что может быть причиной?). Это выглядит как странный способ проверить, подключен ли он, и делает невозможным определить, умерло ли подключенное устройство, но после отправки некоторых данных.

Помимо подключения / отключения при каждой проверке, что я могу сделать? Могу ли я вручную отправить протокол активности tcp или установить соединение более низкого уровня, которое позволит мне проверить подключение без отправки реальных данных, которые потенциально может обработать удаленный сервер?

Ответы [ 5 ]

2 голосов
/ 21 апреля 2009

Я бы рекомендовал не оставлять свой (одиночный) тестовый сокет подключенным - устанавливайте новое соединение каждый раз, когда вам нужно провести опрос. Каждая система балансировки нагрузки / доступности сервера, которую я когда-либо видел, использует этот метод вместо постоянного соединения.

Если удаленный сервер не ответил в течение разумного периода времени (например, 10 секунд), пометьте его как «выключенный». Используйте таймеры и сигналы вместо кодов ответов функций для обработки этого тайм-аута.

1 голос
/ 21 апреля 2009

"становится трудно определить, когда удаленный хост отключается"

Правильно. Это особенность TCP. Весь смысл TCP в том, чтобы иметь постоянное соединение между портами. Теоретически приложение может отбросить и повторно подключиться к порту через TCP (библиотеки сокетов не обеспечивают достаточной поддержки для этого, но это часть протокола TCP).

0 голосов
/ 11 февраля 2016

Вы можете использовать Файлы псевдоустройства Bash для соединения TCP / UDP с определенным портом ввода / вывода, например:

printf "" > /dev/tcp/example.com/80 && echo Works

Это откроет соединение, но ничего не отправит. Вы можете проверить это:

nc -vl 1234 &
printf "" > /dev/tcp/localhost/1234

Для простого мониторинга используйте cron с вышеуказанной командой или используя watch:

watch bash -c 'echo > /dev/tcp/localhost/1234 && echo Works || echo FAIL'

Однако рекомендуется использовать специальные инструменты, предназначенные для этого, такие как Monit, Nagios и т. Д.

монит

Вот пример правила с использованием Monit (monit):

# Verify host.
check host example with address example.com
  if failed
    port 80
    protocol http
  then alert
0 голосов
/ 21 апреля 2009

Теоретически можно рассылать пакеты поддержки активности. Но чтобы установить очень низкие интервалы, вам может понадобиться копаться в сырых сокетах. Кроме того, ваш хост может игнорировать его, если он входит слишком быстро.

Лучший способ проверить, жив ли хост в соединении TCP, - это отправить данные и дождаться пакета ACK. Если поступит пакет ACK, функция SEND вернет ненулевое значение.

0 голосов
/ 21 апреля 2009

пинг был изобретен для этой цели

также вы можете отправлять искаженные TCP-пакеты в пункт назначения. Например, в заголовках TCP есть флаг для подтверждения окончания передачи, это сообщение FIN. Если вы отправите сообщение с ACK и FIN, удаленный хост должен подать жалобу с ответным пакетом, и вы сможете оценить время прохождения туда-обратно.

...