Назад | Перейти на главную страницу

systemctl start trafficserver ждать запуска

У меня есть скрипт, который устанавливает и настраивает сервер трафика:

yum install -y trafficserver
systemctl start trafficserver

traffic_line -s proxy.config.url_remap.remap_required -v 0
traffic_line -s proxy.config.reverse_proxy.enabled -v 0

Проблема в, traffic_line не работает с:

[подключить] ОШИБКА (main_socket_fd 3): нет такого файла или ошибки каталога: не удалось подключиться к порту управления, убедитесь, что traffic_manager запущен

Это потому что systemctl start немедленно возвращается, не дожидаясь фактического запуска сервера трафика.

Есть ли способ сказать systemctl start возвращаться только после запуска службы?

Если это невозможно, есть ли команда, которую я могу запустить после systemctl start на самом деле дождаться запуска службы?

Это потому что systemctl start немедленно возвращается, не дожидаясь фактического запуска сервера трафика.

Есть ли способ сказать systemctl start возвращаться только после запуска службы?

systemctl start делает подождите, пока служба будет готова (кроме случаев, когда вызывается с --no-block), сервису просто нужно указать, что правильно (т. е. не использовать Type=simple). Если служба не сообщает systemd, когда она готова, никаких вариантов systemctl is-active, systemctl showи др. поможет вам.

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

В качестве альтернативы вы можете использовать либо Type=forking (служба разветвляется, и основной PID закрывается, когда разветвленная служба готова) или Type=notify (служба звонит sd_notify(0, "READY=1") как только он будет готов).

К сожалению, все эти решения требуют поддержки со стороны trafficserver - использовать сокет systemd вместо того, чтобы выделять его собственный, выполнить ответвление и подождать в основном процессе или вызвать sd_notify. systemd не может волшебным образом угадать, когда сервер будет готов, если сервер не сотрудничает :)


Посмотрев на trafficserverНемного исходного кода, похоже, что он действительно может поддерживать Type=forking - сервер порождается выделенным traffic_cop команда, которая, кажется, ждет, пока сервер не заработает, и выполняет базовое тестирование (по крайней мере, код выглядит так). Поэтому, если вы измените тип службы, это может просто сработать:

# /etc/systemd/system/trafficserver.service.d/type-forking.conf
[Service]
Type=forking

После нескольких попыток я наконец заставил его работать.

Первая попытка

Покопавшись в справке по systemctl, я нашел is-active команда:

$ systemctl is-active trafficserver
active

Поэтому я написал сценарий оболочки, чтобы дождаться, пока служба станет активной:

while true; do
    if [ $(systemctl is-active trafficserver) == "active" ]; then
        break
    fi

    sleep 1
done

К сожалению, хотя этот сценарий работает должным образом, когда я тестирую его с помощью start / stop, Я все еще получал ту же ошибку при запуске traffic_line команды сразу после него. Я думаю, что служба считается активной до того, как фактические процессы будут полностью запущены (вероятно, это вопрос миллисекунд).

Вторая попытка

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

while [ ! -f /run/trafficserver/manager.lock ]; do
  sleep 1
done

Та же проблема: когда PID-файл менеджера сервера трафика записан, он фактически еще не готов принимать заказы, поэтому Я все еще получаю сообщение об ошибке.

Черт, Я не хочу использовать шторку sleep.

Третья попытка

В итоге я проверил, что traffic_line Сама команда не дает сбоев:

while ! traffic_line --status &> /dev/null; do
    sleep 1
done

И это работает!

Приятно, но...

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

Если вы знаете более общий ответ на этот вопрос, поделитесь им.

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

$ systemctl show trafficserver -p SubState,ActiveState
ActiveState=active
SubState=running

После этого вы сможете запустить вторую часть вашего скрипта.

Самый простой способ - добавить в скрипт засыпание:

sleep 30

Или вы могли бы контролировать работу как Вот