При выполнении Сценария PHP при запуске ПОСЛЕ ТОГО, КАК запустились другие сервисы

Для получения регулярных погодных обновлений в мою базу данных Redis, схема, которую я пытаюсь использовать, следующие

У меня есть Сценарий PHP, который выбирает погоду от соответствующей погоды API. Это проходит примерно так

<?php
 function getWeather()
 {
  if (weatherupdaterequired)
  {
   //weather API call
   //parse and store to database
  }
 }

 while (true)
 {
  getWeather();
  sleep(30);
 }
?>

который хранится в моем /usr/local/bin папка. В той же папке у меня есть сценарий оболочки, runweather который делает просто это:

#!/bin/sh
nohup php /usr/local/bin/echoweather.php  >/dev/null 2>&1 &

Я обычно склонен использовать #!/bin/bash но в этом экземпляре я нашел, что, когда выполнено при запуске - поскольку Вы будете видеть ниже - только #!/bin/sh работы. Я предполагаю, что это имеет некоторое отношение к оболочке удара, еще не являющейся доступным.

Я затем создал символьную ссылку на runweather

ln -s /usr/local/bin/runweather /etc/init.d/runweather

и затем другая символьная ссылка

ln -s /etc/init.d/runweather /etc/rc2.d/S99runweather

Несколько пояснительных записок

  1. Это /usr/local/bin/echoweather.php это делает всю реальную работу. Это работает в интервалах 30-х и снах, если не работающих
  2. Только до завершения каждого выполнения это помещает эфемерный ключ Redis $redis-setEx ("сообщение о погоде", 29, $echoCount)', который я могу использовать для слежения за его здоровьем
  3. Размещение сценария оболочки, который добирается echoweather.php выполнение при запуске в /usr/local/bin, затем symlinking это в /etc/init.d только к затем символьной ссылке это снова в /etc/rc2.d мог бы выглядеть замысловатым. Я сделал это, так как я нашел это, если я помещаю фактический сценарий оболочки в /etc/init.d и затем символьная ссылка это к /etc/rc2.d это не выполняется.

Эта схема работает. Я несколько раз перезагружал свой сервер и проверял здоровье echoweather.php путем поиска weatherreport ключ в Redis через redis-cli - всегда представляет и исправляет. Однако я - любитель разряда когда дело доходит до контакта со сценариями запуска Ubuntu. Возможно, существует более простой способ сделать вещи? Я был бы очень обязан любому, кто смог комментировать.

1
задан 24 February 2020 в 11:08

1 ответ

Если Вы не выполняете версию EOL Ubuntu, Ваша init система уже systemd базирующаяся, так использование, это - правильный способ пойти. Некоторые люди могли бы сказать Вам использовать Type=idle для Вашей сервисной единицы, но: (из systemd страницы справочника):

Обратите внимание, что использование любого типа кроме простого возможно задерживает процесс начальной загрузки, поскольку менеджер по сервису должен ожидать сервисной инициализации для завершения. Следовательно рекомендуется не напрасно использовать любые типы кроме простого. (Также обратите внимание, что обычно не рекомендуется использовать неактивный или oneshot для продолжительных сервисов.)

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

  1. Ваш сетевой стек должен функционировать;
  2. Ваш сценарий должен работать поздно в процессе начальной загрузки, и;
  3. Ваш сценарий должен бежать за Redis, полностью запускается.

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

  1. Единицы, который строго требует соединения настроенной сети, должны сдержаться network-online.target, так наша единица Wants это и должно только работать After эта цель;
  2. multi-user.target настраивает многопользовательскую систему и заканчивается, после того как все требуемое для этого сделано, таким образом, единица, вероятно, Wants и WantedBy это. Поскольку мы действительно хотим, чтобы наша единица работала поздно в процесс начальной загрузки, выполняя его After эта цель - то, что мы хотим также;
  3. Redis является частью многопользовательской системы, которую мы настраиваем, и наша единица может только произвести свои желаемые эффекты если Redis и выполняющий так его Requires Redis для выполнения и мы должны только загрузиться After это.

Имея это в виду, мы можем записать a echoweather.service файл в /etc/systemd/system/ это принимает все это во внимание:

[Unit]
Description=Gets regular weather updates into my Redis database
Wants=network-online.target multi-user.target
Requires=redis-server.service
After=network-online.target multi-user.target redis-server.service

[Service]
PIDFile=/var/run/echoweather.pid
ExecStart=/usr/bin/php /usr/local/bin/echoweather.php  >/dev/null 2>&1 &
Type=forking
KillMode=process

[Install]
WantedBy=multi-user.target

После того как это сделано, перезагрузите свои файлы демона, включите Вашу сервисную единицу и выполните Ваш процесс:

$ sudo systemctl daemon-reload
$ sudo systemctl enable echoweather.service
$ sudo systemctl start echoweather.service
3
ответ дан 17 March 2020 в 00:18

Другие вопросы по тегам:

Похожие вопросы: