Я установил Tomcat 8.5 и могу запустить его вручную, например:

su tomcat startup.sh

работает должным образом и tomcat может обслуживать порт 8080.

Мне нужно автоматизировать запуск, поэтому я создал файл /etc/systemd/system/tomcat-prod.service:

[Unit]
Description=Tomcat 8.5 servlet container - Production
After=network.target

[Service]
Type=forking

ExecStart=/opt/appservers/production/apache-tomcat-8.5.37/bin/startup.sh
ExecStop=/opt/appservers/production/apache-tomcat-8.5.37/bin/shutdown.sh

User=tomcat
Group=tomcat   

[Install]
WantedBy=multi-user.target

Файл специально создан, все мои переменные env находятся в setenv.sh. Я попытался запустить его с помощью:

# systemctl daemon-reload
# systemctl start tomcat-prod

По какой-то причине выше приводит к выходу Tomcat сразу после запуска. Я нигде не получаю логов, объясняющих почему. Tomcat создает пустой файл catalina.out при запуске, а состояние systemctl tomcat-prod дает только следующее:

tomcat-prod.service - контейнер сервлета Tomcat 8.5 - загружен продукт: загружен (/etc/systemd/system/tomcat-prod.service; включен; предустановка поставщика: отключен) активный: не выполнен (результат: код выхода) с пт 2019- 01-04 08:08:27 UTC; 3 с. Назад Процесс: 3583 ExecStop =/opt/appservers/production/apache-tomcat-8.5.37/shutdown.sh (код = выход, состояние = 203/EXEC) Процесс: 3569 ExecStart =/opt/appservers/production/apache- tomcat-8.5.37/bin/startup.sh (код = выход, статус = 0/ УСПЕХ) Главный PID: 3581 (код = выход, статус = 0/ УСПЕХ)

Янв 04 08:08:27 * .net startup.sh [3569]: во время запуска найден существующий файл PID. Янв 04 08:08:27 * .net startup.sh [3569]: удаление / очистка устаревшего файла PID.

Может ли кто-нибудь указать мне правильное направление?

1 ответ1

2

Systemd отслеживает "основной процесс" каждого сервиса, чтобы он мог точно знать, активен ли сервис или нет. Когда основной процесс завершается, диспетчер служб предполагает, что служба аварийно завершилась или просто остановилась. И когда служба останавливается, все ее оставшиеся процессы автоматически уничтожаются, чтобы обеспечить чистое состояние для будущих запусков.

Для сервисов Type = forking определить, какой процесс является "основным", может быть довольно сложно, особенно если он скрыт за слоями и слоями и слоями сценариев оболочки. Эвристика по умолчанию в systemd хорошо работает для обычных демонов, но в вашем случае они, вероятно, неверно определяют один из этих слоев шеллскрипта как основной процесс, а не сам tomcat. Поэтому, как только сценарий завершается, предполагается, что служба остановлена, а ее остатки (включая реального демона) уничтожены.

У вас есть два варианта:

  • Явно укажите основной процесс, используя "pidfile". Это традиционный метод, используемый SysVinit. Ваши сценарии запуска уже хранят идентификатор процесса демона Tomcat в каком-либо файле, поэтому ваш модуль tomcat.service должен ссылаться на него, используя PIDFile= . При этом диспетчеру службы не потребуется эвристика автоопределения, а будет просто отслеживать предоставленный PID в качестве основного процесса.

  • Полностью избавьтесь от сценариев оболочки и запустите Tomcat напрямую из опции ExecStart = . Это рекомендуемый метод для systemd, и вы можете найти примеры .service модулей, уже написанных упаковщиками различных дистрибутивов. Например, Arch Linux (Tomcat 8 с Jsvc) .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .