У меня есть скрипт, который устанавливает и настраивает сервер трафика:
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
Или вы могли бы контролировать работу как Вот