Почему systemd не знает, произошел ли сбой службы?

Итак, как прокомментировал OP, перемещение адреса загрузки решает проблему. Это подчеркивает опасность использования fdt _high(или, в других случаях, initrd _high ), чтобы остановить U -Boot от перемещения содержимого.В таких случаях, как образы FIT, где U -Boot имеет хорошее представление о том, насколько велика каждая из частей, вы обычно хотите использовать bootm _size , чтобы сообщить U -Boot, сколько памяти (с начала первого банка )для использования при перемещении содержимого для загрузки ОС. В этом конкретном случае, когда вы хотите, чтобы initrd находился в верхней памяти, вам нужно использовать определенное значение для fdt _high , которое находится в пределах пространства, которое ядро ​​увидит (, которое зависит от архитектуры. и версия ядра в некоторых случаях, пожалуйста, обратитесь к документации ОС, например linux/Documentation/arm64/booting.txt ).

1
15.04.2020, 19:48
1 ответ

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

Первая проблема, которую я вижу :systemd не использует сценарии запуска/остановки в /etc/init.d, для этого это только дополнение совместимости. Вместо этого systemd использует юнит-файлы, то есть файл конфигурации для всех своих служб.

Модуль systemd sysv init compat эффективно генерирует юнит-файл для всех служб в /etc/init.d. Это не всегда нормально,потому что скрипты инициализации пропускают требуемую информацию (или из них невозможно извлечь ).

Этот модуль совместимости работает так, что systemd считает, что сценарий инициализации завершился неудачно и, следовательно, служба не работает, если ее код выхода не равен -нулю. Нулевой код выхода означает успешное выполнение. Если скрипт инициализации глючит и выдает нулевой код выхода даже в случае сбоя, он обманет systemd.

Наиболее вероятная причина ошибки вашего сценария инициализации заключается в том, что он запускает процесс в фоновом режиме, а затем завершается всегда с нулем. Мой общий опыт с большинством сценариев инициализации, написанных пользовательскими поставщиками, заключается в том, что... возможно, большинство из них имеют большое место для улучшения. Не доверяйте им, посмотрите, что они делают, и исправьте их. В вашем случае лучше всего проверить,

  • Как он запускает ваше Java-приложение
  • Где она начинается
  • От имени какого пользователя запускается

И воспроизвести ту же функциональность с помощью юнит-файла.

Невозможно автоматически -перезапустить сценарии инициализации из systemd, но это возможно из юнит-файлов.

Обратите внимание: если программа на Java случайно падает, это тоже серьезная проблема. Все нормальные Java-фреймворки корректно обрабатывают собственные фатальные ошибки (, они перехватывают все исключения, регистрируют их и продолжают работу ).

Еще одна весьма вероятная ошибка в скрипте инициализации заключается в том, что он не находит вашу JVM (скорее всего :/usr/bin/java ), поэтому он заменяет его пустой строкой, в результате чего он пытается чтобы запустить флаги JVM как команду оболочки. Очевидно, что в вашей системе нет команды -Xms96M, но сработает /usr/bin/java -Xms96M....

Пример юнит-файла для весеннего загрузочного приложения:

[Unit]
Description=Crm Spring Boot App Example
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/java -Xms96M...other flags... your.spring.boot.jar
User=exampleuser
Group=examplegroup
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=exampleapp
WorkingDirectory=/path/to/app/home

[Install]
WantedBy=multi-user.target
Alias=exampleapp.service

Этот модульный файл также перенаправляет стандартный вывод и ошибки процесса Java в системный журнал.

Для автоматического перезапуска приложения введите

RestartSec=5s
Restart=on-failure

в секцию [Service].

Учебник по systemd есть на GoLinuxCloud.com .

3
19.03.2021, 02:28

Теги

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