CentOS 7 загружается слишком быстро, и сеть не готова при выполнении скриптов cron

9

Я только что обновил CentOS 6.5 до 7.0, и я не слишком доволен, потому что новое systemd, вероятно, доставляет мне проблемы. Кажется, это просто слишком быстрая загрузка, асинхронный запуск процессов и разрушение служебных зависимостей.

Например, у меня есть несколько скриптов, crondкоторые запускаются после перезагрузки:

@reboot    /root/scripts/check_gmail.sh
@reboot    /root/scripts/start_gps_listener.sh

Это приводит к всевозможным странным ошибкам (показывает только одну из них):

Warning: stream_socket_client(): unable to connect to tcp://192.168.20.4:4001 
  (Network is unreachable) in /root/scripts/check_gmail.php on line 137
  ERROR: Network is unreachable (101)

Выше я пишу в сокет TCP. Для меня довольно ясно, что crondзапускается до того, как сеть должным образом инициализируется как network is unreachable.

То же самое относится и к Apache и MySQL (MariaDB). MySQL довольно медленно запускается (много данных), что означает, что и Apache, и многие мои crondскрипты запуска не работают, поскольку база данных MySQL не работает во время вызова скриптов.

Я пытался настроить зависимости, но безуспешно; Я добавил networkи mysqlуслуги [Unit](как видно с systemctl list-dependencies). В идеале все сервисы ждут, пока MySQL будет запущен:

vi /lib/systemd/system/httpd.service
  [Unit]
  Description=The Apache HTTP Server
  After=network.target remote-fs.target nss-lookup.target network.service mysql.service

vi /lib/systemd/system/crond.service
  [Unit]
  Description=Command Scheduler
  After=syslog.target auditd.service systemd-user-sessions.service time-sync.target network.service mysql.service

При загрузке с вышеупомянутым я получаю те же ошибки. Я также получаю электронные письма, так mailqкак сеть / DNS не готова при обработке cron-скриптов. Через несколько минут после запуска они отправляются правильно.

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

Обратите внимание, что я не уверен, systemdчто это моя проблема - это всего лишь моя теория о том, что я могу прочитать из сети.

DHS
источник
Не могли бы вы опубликовать вывод grep -i concurrency /etc/default/rcS? Возможно, я путаю мои системы инициализации, но, похоже, я помню, что контролирует, ожидают ли процессы завершения друг друга.
Terdon
У меня нет файлов с/etc/default/rc*
DHS
Извините, я не знаю, где будет эквивалент CentOS. Я думал о том, что здесь описано для Debian, который запускает службы параллельно. В вашем случае может быть что-то подобное.
Terdon
2
Попробуйте добавить Requires=network.targetк единицам выше.
Кейси
Все еще та же самая проблема после вставленной Requires=network.targetв/lib/systemd/system/crond.service
DHS

Ответы:

9

После гораздо большего чтения я нашел решение, которое работает для меня.

Я прочитал это руководство, Запуск сервисов после запуска сети . Небольшая цитата из руководства:

Это обеспечит работоспособность всех настроенных сетевых устройств и назначение IP-адреса до продолжения загрузки.

Это именно то, что я хотел, поэтому я включил эту службу и установил правило зависимости в файле службы для crond:

[root@srv]# systemctl enable NetworkManager-wait-online

[root@srv]# vi /lib/systemd/system/crond.service
  Requires=network.target
  After=syslog.target auditd.service systemd-user-sessions.service time-sync.target network.target mysqld.service

Поскольку mysqldвсе еще основано на старом, init.dмне нужно было создать systemdсервис, как предложено здесь, включение systemctl отличается от запуска systemctl :

[root@srv]# vi /lib/systemd/system/mysqld.service
  [Unit]
  Description=MySQL Server
  After=network.target
  [Service]
  Type=forking
  ExecStart=/etc/rc.d/init.d/mysql start
  ExecStop=/etc/rc.d/init.d/mysql stop
  [Install]
  WantedBy=multi-user.target

[root@srv]# systemctl daemon-reload
[root@srv]# chkconfig mysql off
[root@srv]# systemctl enable mysqld

И, наконец, настройте службу Apache на запуск после MySQL:

[root@srv]# vi /lib/systemd/system/httpd.service
  Requires=mysqld.service
  After=network.target remote-fs.target nss-lookup.target mysqld.service

Это работает для меня по крайней мере.

Я использовал эти команды, чтобы потом проверить, где я ясно вижу, что сеть запущена, по крайней мере, до MySQL и Apache. Я crondнигде не вижу, но вижу, что это работает в моих скриптах:

[root@srv]# systemd-analyze critical-chain
  multi-user.target @10.510s
    + httpd.service @10.344s +165ms
      + mysqld.service @9.277s +1.065s
        + network.target @9.273s
          + network.service @8.917s +355ms
            + iptables.service @444ms +157ms
              + basic.target @443ms
                [CUT]

Несколько других полезных команд, которые я использовал:

# See exactly what takes how long (who to blame for the delay)
[root@srv]# systemd-analyze blame

# Check available names that can be used in the service files
[root@srv]# systemctl list-unit-files

Если кто-нибудь может найти лучший способ сделать это, пожалуйста, поделитесь.

DHS
источник
+1 за публикацию команд, которые вы использовали для отладки. Я был в состоянии решить действительно неприятный узел проблем с systemd-analyze critical-chain. Мало того, что я собираюсь использовать это часто, но я внезапно продан systemd. Спасибо!
Брайан Топпинг
Вы не должны изменять служебные файлы, управляемые вашим менеджером дистрибутива. Вместо этого вам лучше использовать выпадающие файлы конфигурации. Смотрите ответ на Как переопределить или настроить системные сервисы?
Людовик Ронсин