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

Проверка доступности сетевого сервиса помогает отличить сбой приложения от проблем с DNS, маршрутизацией или сетевыми правилами. Для такой диагностики недостаточно отправить запрос на произвольный порт: скрипт должен проверять конкретный узел и протокол, ограничивать время ожидания и фиксировать результат.
Что именно проверять
На базовом уровне проверяется возможность установить TCP-соединение с заданными адресом и портом. Успешное соединение означает, что узел отвечает на этом уровне, но не доказывает, что приложение корректно обрабатывает запросы. Сервис может принять подключение, а затем зависнуть или вернуть ошибку.
Для более полной проверки нужен запрос прикладного уровня. Например, HTTP-проверка может оценивать код ответа, а проверка TLS — факт установления защищённого соединения и корректность сертификата. Выбранная проверка должна соответствовать цели: доступность порта, готовность приложения или выполнение конкретной операции — разные условия.
Тайм-ауты и обработка ошибок
Без тайм-аута скрипт может надолго остановиться на недоступном узле. Значение задают явно и отдельно для соединения и ответа приложения, если используются оба этапа. Ошибки DNS, отказ в соединении и истечение времени ожидания стоит различать: они указывают на разные участки возможного сбоя.
Простой пример TCP-проверки на Python:
import socket
import time
def check_tcp(host: str, port: int, timeout: float = 3.0) -> dict:
started = time.monotonic()
try:
with socket.create_connection((host, port), timeout=timeout):
return {
"host": host,
"port": port,
"status": "available",
"elapsed_ms": round((time.monotonic() - started) * 1000),
}
except socket.gaierror as error:
status = f"dns_error: {error}"
except TimeoutError:
status = "timeout"
except OSError as error:
status = f"connection_error: {error}"
return {"host": host, "port": port, "status": status}
Монотонные часы подходят для измерения длительности: их показания не зависят от перевода системного времени. Скрипт закрывает сокет после проверки, а ошибки возвращает как данные, чтобы вызывающий код мог записать их в журнал или обработать отдельно.
Повторные попытки и результаты
Одиночная неудачная попытка может быть кратковременным сетевым сбоем. Повторы помогают уменьшить число ложных тревог, но должны быть ограничены по количеству и времени. Между попытками обычно делают небольшую паузу. Бесконечный цикл повторов маскирует проблему и создаёт лишнюю нагрузку.
Результат полезно записывать в структурированном виде: имя проверки, адрес, порт, время выполнения, статус и текст ошибки. Для регулярного мониторинга важны единый формат вывода и отметка времени. Секреты, токены и содержимое запросов в журнал помещать не следует.
Запуск и безопасность
Список проверяемых узлов лучше хранить отдельно от логики скрипта, например в конфигурационном файле. Это упрощает изменение набора проверок и снижает риск случайного обращения к посторонним адресам. Проверки должны запускаться только для систем, на которые есть разрешение.
Перед автоматизацией полезно проверить сценарии: доступный сервис, закрытый порт, неверное имя узла и медленный ответ. Эти случаи показывают, различает ли скрипт типы ошибок и завершается ли он предсказуемо. TCP-проверка остаётся только сетевым тестом; для оценки работоспособности приложения нужны проверки его собственного протокола и ожидаемого ответа.