Назад | Перейти на главную страницу

tomcat6 в CentOS 6: невозможно остановить / перезапустить службу

У меня проблема с остановкой и запуском tomcat6 (пакет из репозиториев). Я видел несколько коробок CentOS 6 и RHEL 6.

Симптомы в том, что когда я хочу перезапустить или остановить tomcat6, он просто не работает. Кажется, это происходит только после того, как он проработает некоторое время. У меня есть свежая установка CentOS 6, и я смог ее перезапустить, но больше нет.

Вот что я вижу:

 # service tomcat6 restart
 Stopping tomcat6:                                          [FAILED]
 Starting tomcat6:                                          [FAILED]

Когда я пытаюсь пройти /usr/sbin/tomcat6:

# /usr/sbin/tomcat6 stop
/usr/sbin/tomcat6: line 60: /logs/catalina.out: No such file or directory

И вывод из /var/log/tomcat6/catalina.out:

Oct 22, 2012 4:53:31 PM org.apache.catalina.startup.Catalina stopServer
SEVERE: Catalina.stop:
java.net.ConnectException: Connection refused
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:327)
    at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:193)
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
    at java.net.Socket.connect(Socket.java:546)
    at java.net.Socket.connect(Socket.java:495)
    at java.net.Socket.<init>(Socket.java:392)
    at java.net.Socket.<init>(Socket.java:206)
    at org.apache.catalina.startup.Catalina.stopServer(Catalina.java:424)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)

Я поискал в сети и вижу, что я не одинок, но не нашел подходящего решения, отсюда и мой вопрос.

Кстати: я не слишком знаком с котом. Да и еще: первый пост! Так что будь любезен;)

Проблема

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

Дело в том, что Tomcat довольно легко попасть в какую-то ситуацию, когда его нельзя убить через порт управления ... или даже через TERM сигнал.

Давайте рассмотрим, как можно убить Tomcat в порядке эскалации:

  1. Убиваем Tomcat через порт управления. Это значение по умолчанию, и это то, что сначала пытается выполнить собственный сценарий завершения работы Tomcat. Это не сработает, если Java-процесс завис по той или иной причине. Все отчеты, которые вы видите в Интернете, где люди жалуются, что Tomcat не останавливается, более или менее всегда находятся в этом переулке. На самом деле это не вина Tomcat. Достаточно легко создать веб-приложение, которое приведет к зависанию всего контейнера или невозможности его остановки с помощью этого метода.

  2. Убить Tomcat, отправив процессу Java TERM сигнал. Это более сильный способ убить Tomcat, чем в (1), и собственный сценарий выключения Tomcat попытается это сделать, но он активируется только в том случае, если вы установили CATALINA_PID переменная в вашем Tomcat setenv.sh. (что настоятельно рекомендуется в любом случае). Убить процесс Unix / Linux, отправив ему TERM сигнал по умолчанию для kill команда из ОС. Это вежливый способ сказать процессу Unix / Linux о смерти. К сожалению, даже это в редких случаях не убивает процесс Tomcat.

  3. Убить Tomcat, отправив процессу Java KILL сигнал. (из командной строки ОС это будет kill -9 <pid>). Это будет всегда убить процесс и использовать его в крайнем случае. Проблема здесь в том, что стандартный сценарий выключения Tomcat никогда не будет пытаться это сделать, даже если методы (1) и (2) не работают. Поэтому, если вы действительно хотите убедиться, что Tomcat был убит, у вас нет другого выбора, кроме как реализовать собственный сценарий оболочки вокруг собственного сценария завершения работы Tomcat.

При запуске Tomcat в производственной среде вам действительно нужно подумать, сможете ли вы жить в ситуации, когда Tomcat не умирает (или не перезагружается) при запуске, например. service tomcat restart. Вы можете делать это через cron, и в этом случае вы наверняка ожидаете детерминированного результата, верно?

Рекомендации

  • Всегда используйте Tomcat setenv.sh файл, в котором вы определяете CATALINA_PID. Это, по крайней мере, даст вам способ №2, описанный выше. Tomcat's setenv.sh по умолчанию файл не существует, поэтому вы должны создать его самостоятельно.

  • Создайте сценарий оболочки вокруг собственных сценариев Tomcat, который гарантирует, что Tomcat действительно умирает.

Там, где я работаю, мы реализовали это на всех хостах, на которых Tomcat работает как служба. Это та же проблема / решение для любого варианта Unix / Linux.

Я столкнулся с этим сегодня. В моем случае причиной был устаревший файл pid.

Tomcat запустился нормально после выполнения rm /var/run/tomcat6.pid.

Я столкнулся с той же проблемой. Для меня это произошло из-за проблемы с правами / владельцем файла. Когда init.d или /usr/sbin/tomcat6 скрипт не может прочитать /etc/tomcat6/tomcat6.conf файл, затем значение ${CATALINA_BASE} становится пустым. Так ${CATALINA_BASE}/logs/catalina.out в строке 60 становится /logs/catalina.out.

Я запускаю Tomcat7 на CentOS; раньше я работал с Tomcat6.

Чтобы перезапустить Tomcat, я всегда просто захожу в каталог bin своей установки Tomcat и запускаю shutdown.sh, затем startup.sh. Вы можете сделать это таким образом в качестве резервного метода.