Зависания при остановке, когда работает прокси, редко бывают ошибкой VPN, даже если VPN — последнее, что видно на экране. Приложения за прокси всё ещё ждут путь, который вот-вот исчезнет, а юнит, владеющий туннелем, ещё не получил команду закрыть его. То, что выглядит как медленный сервис, обычно оказывается проблемой порядка. Упорядочивание решает больше таких случаев, чем любое изменение таймаута.

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

Составьте список юнитов, прежде чем что-то останавливать

Запишите юнит приложения, юнит прокси и владельца VPN, участвующих в обычном запуске. Добавьте любой резолвер или вспомогательный компонент, у которого есть собственное завершение, — именно их забывают в два часа ночи. Без этого списка первая же команда остановки, которую вы введёте, выберет жертву наугад.

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

Сначала завершите работу, затем остановите потребителя

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

Запросы, которые были в полёте во время остановки, должны попасть в запись, потому что именно отсюда берётся шторм повторных попыток при следующем запуске.

ExecStop и ExecStopPost — разные инструменты

ExecStop= — это синхронная операция остановки; ExecStopPost= — это очистка, которая выполняется даже после неудачного запуска. Команда остановки, которая лишь посылает сигнал процессу и возвращает управление, позволяет systemd двигаться дальше, пока потребитель всё ещё сбрасывает данные. То, что должно произойти в любом случае, относится к пост-варианту, а то, что должно блокировать остановку, — к синхронному. Проверяйте действующий юнит и его drop-in-файлы, а не правьте файл пакета на месте.

Граф зависимостей упорядочивает задания остановки. Он не превращает асинхронный скрипт в синхронный и не заставляет удалённое приложение зафиксировать свои данные.

Ограничьте остановку и знайте цену этого ограничения

TimeoutStopSec= ограничивает и команду остановки, и собственное завершение службы, а по истечении лимита systemd переходит к принудительному убийству. Выбирайте значение по реальному поведению приложения при сбросе данных и записывайте, что может быть потеряно, когда лимит сработает. Число, выбранное потому, что машина должна выключиться быстрее, — это настройка потери данных под другим именем.

Когда остановка всё ещё медленная, зафиксируйте юнит, его дочерние процессы, интервал журнала и результат таймаута. Сокращать все таймауты или хвататься за массовое убийство — так чистые остановки превращаются в повреждённое состояние при следующей загрузке.

Отключайтесь через владельца, затем проверьте три случая

Когда потребители остановлены, попросите менеджер, владеющий туннелем, отключиться: экземпляр systemd, активное соединение NetworkManager или сервис поставщика. Убийство постороннего процесса OpenVPN не обязательно удаляет сессию, которая предоставила маршрут, а прокси с политикой перезапуска может заново создать запрос, пока вы разбираете путь. Согласуйте эту политику с плановой остановкой до начала.

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

Похожие статьи