Программирование 10 ноября 2026

Создание скрипта для проверки доступности сетевых сервисов

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

Проверка доступности сетевого сервиса помогает отличить сбой приложения от проблем с 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-проверка остаётся только сетевым тестом; для оценки работоспособности приложения нужны проверки его собственного протокола и ожидаемого ответа.