Java Applications — Создание Init скриптов для Linux

При установке в Linux сторонних приложений написанных на Java возникает множество вопросов, один из них — как удобнее всего управлять запуском/остановкой/перегрузкой таких приложений? В идеале хотелось бы создать init-скрипты и добавить их в init систему Linux. Такой метод самый правильный с точки зрения операционной системы Linux и удобный как для пользователей так и для админов. Но реальность такова что большинство java-приложений распространяются в виде архивов в которых, в лучшем случае, включены скрипты для запуска, настройки, остановки и еще черт знает чего 🙂
В данной статье на примере приложений Pentaho-BI/Pentaho-DI я решил показать как используя java-wrapper создать init-скрипты для CentOS Linux для управления сервисом как от имени обычного пользователя, так и от root-а.

Сначала разберемся с запуском Pentaho BI-Server, у него есть shell скрипты запуска и остановки, осталось только соблюсти все формальности для добавления их в init систему. В директории /etc/init.d/ я создал такой файлик:

[root@pentahosrv ~]# cat /etc/init.d/pentaho
#!/bin/sh
### BEGIN INIT INFO
# Provides: start-pentaho stop-pentaho
# Required-Start: network postgresql-9.3
# Required-Stop: postgresql-9.3
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: Pentaho BA Server
### END INIT INFO

case "$1" in
"start")
  su - pentaho -c "/home/pentaho/biserver-ce/start-pentaho.sh"
  ;;
"stop")
  su - pentaho -c "/home/pentaho/biserver-ce/stop-pentaho.sh"
  ;;
*)
  echo "Usage: $0 { start | stop }"
  ;;
esac
exit 0
[root@pentahosrv ~]#

Даем права на выполнение:

[root@pentahosrv ~]# chmod +x /etc/init.d/pentaho
[root@pentahosrv ~]#

Добавляем скрипт в init-систему CentOS:

[root@pentahosrv ~]# chkconfig --add pentaho

Проверим, что теперь у нас с автозапуском biserver-а:

[root@pentahosrv ~]# chkconfig --list |grep pentaho
pentaho         0:off   1:off   2:on    3:on    4:on    5:on    6:off
[root@pentahosrv ~]#

Также, согласно официальной документации, в файлике start-pentaho.sh нужно изменить последний if с

if [ "$errCode" = 0 ]; then

на

if [ "$?" = 0 ]; then

Ну вот, теперь от пользователя root можно рулить сервисом biserver-ce стандартными средствами Linux

[root@pentahosrv ~]# service pentaho start
[root@pentahosrv ~]# service pentaho stop
[root@pentahosrv ~]# service pentaho restart

Отлично! То чего я и хотел 🙂
Поехали дальше ….

C Pentaho-DI ситуация чуть посложнее так как shell скриптов для запуска и остановки сервиса в архиве с программкой нету (по крайней мере в CE версии). В таком случае можно воспользоваться сторонним приложением — java wrapper-ом. Их существует огромное множество, я выбрал то что нагуглилось первым, это был «Java Service Wrapper» Community Edition для Linux x86 64-bit от компании Tanuki Software
Напомню, цель — создать init-скрипт для java-приложения Pentaho Data-Integration CE Edition в Cent OS Linux. Data-Integration также как и Biserver будет запускаться от обычного пользователя pentaho.
Делал как написано в официальной документации. Вот листинг домашней директории пользователя pentaho:

pentaho@pentahosrv:~$ ls -l
total 21424
drwxr-xr-x  2 pentaho pentaho     4096 Dec  9 12:02 biserver-ce
drwxr-xr-x  2 pentaho pentaho     4096 Dec  9 12:02 data-integration
drwxr-xr-x  3 pentaho pentaho     4096 Dec  9 16:16 install
pentaho@pentahosrv:~$

В install лежат различные архивы с программами, туда же я скачал и java wrapper:

pentaho@pentahosrv:~$ cd install
pentaho@pentahosrv:~/install$ wget -c http://wrapper.tanukisoftware.com/download/3.5.26/wrapper-linux-x86-64-3.5.26.tar.gz

Тут же в директории install распакуем java-wrapper:

pentaho@pentahosrv:~/install$ tar xzvf wrapper-linux-x86-64-3.5.26.tar.gz

Дальше идут необходимые шаги согласно документации:

pentaho@pentahosrv:~/install$ cp wrapper-linux-x86-64-3.5.26/bin/wrapper ../data-integration/launcher/
pentaho@pentahosrv:~/install$ cp wrapper-linux-x86-64-3.5.26/src/bin/sh.script.in ../data-integration/launcher/

Почему я скопировал заготовку для init-скрипта и бинарник wrapper-а в директорию launcher? Потому что в этой директории размещены все бинарники data-integration.
Переходим в директорию /home/pentaho/data-integration/launcher и смотрим что там есть:

pentaho@pentahosrv:~/install$ cd ../data-integration/launcher/
pentaho@pentahosrv:~/data-integration/launcher$ ls -l
total 400
-rw-r--r-- 1 pentaho pentaho    778 Oct  1 13:45 kettle.cfg.xml
-rw-r--r-- 1 pentaho pentaho    193 Oct  1 13:45 launcher.properties
-rw-r--r-- 1 pentaho pentaho  14904 Sep 30 19:19 pentaho-application-launcher-5.2.0.0-209.jar
-rw-r--r-- 1 pentaho pentaho  69452 Dec 12 16:38 sh.script.in
-rwxr-xr-x 1 pentaho pentaho 312520 Dec 12 16:37 wrapper
pentaho@pentahosrv:~/data-integration/launcher$

Опять же, согласно документации wrapper-а, нам нужно заготовку init-скрипта переименовать. Имя скрипта должно соответствовать названию сервиса. Я выбрал — pentaho-di:

pentaho@pentahosrv:~/data-integration/launcher$ mv sh.script.in pentaho-di

Открываем файл для редактирования:

pentaho@pentahosrv:~/data-integration/launcher$ vim pentaho-di

и меняем 2 параметра:

# Application
APP_NAME="pentaho-di"
APP_LONG_NAME="Pentaho DI Server"

Еще раз листинг директории launcher:

pentaho@pentahosrv:~/data-integration/launcher$ cd ..
pentaho@pentahosrv:~/data-integration$ ls -l launcher/
total 400
-rw-r--r-- 1 pentaho pentaho    778 Oct  1 13:45 kettle.cfg.xml
-rw-r--r-- 1 pentaho pentaho    193 Oct  1 13:45 launcher.properties
-rw-r--r-- 1 pentaho pentaho  14904 Sep 30 19:19 pentaho-application-launcher-5.2.0.0-209.jar
-rw-r--r-- 1 pentaho pentaho  69454 Dec 12 16:42 pentaho-di
-rwxr-xr-x 1 pentaho pentaho 312520 Dec 12 16:37 wrapper
pentaho@pentahosrv:~/data-integration$

Даем права на выполнение будущему init-скрипту:

pentaho@pentahosrv:~/data-integration$ chmod +x launcher/pentaho-di

Также, опять согласно документации, надо скопировать необходимые библиотеки:

pentaho@pentahosrv:~/data-integration$ cp ../wrapper-linux-x86-64-3.5.26/lib/libwrapper.so lib/
pentaho@pentahosrv:~/data-integration$ cp ../wrapper-linux-x86-64-3.5.26/lib/wrapper.jar lib/

Ну и собственно копируем заготовку конфига:

pentaho@pentahosrv:~/data-integration$ mkdir conf
pentaho@pentahosrv:~/data-integration$ cp ../wrapper-linux-x86-64-3.5.26/src/conf/wrapper.conf.in conf/wrapper.conf
pentaho@pentahosrv:~/data-integration$

Для логов желательно иметь отдельную директорию:

pentaho@pentahosrv:~/data-integration$ mkdir logs

Теперь надо понять с какими опциями запускается наше приложение. Для этого я посмотрел внутрь скрипта carte.sh:

pentaho@pentahosrv:~/data-integration$ vim carte.sh
....
export OPT
"$DIR/spoon.sh" -main org.pentaho.di.www.Carte "$@"

Тоесть по сути запускается spoon.sh с дополнительными опциями -main org.pentaho.di.www.Carte
Смотрим что в spoon.sh:

............................
# ***************
# ** Run...    **
# ***************
"$_PENTAHO_JAVA" $OPT -jar "$STARTUP" -lib $LIBPATH "${1+$@}"

Понятно что запуск хитрый и непонятный. Куча переменных мешает пониманию. Пробуем просто сделать вывод на экран самой строки запуска. Для этого вместо самого запуска сделаем echo его команды с параметрами:

echo "$_PENTAHO_JAVA" $OPT -jar "$STARTUP" -lib $LIBPATH "${1+$@}"

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

+ echo java -Dorg.mortbay.util.URI.charset=UTF-8 -Xmx512m -XX:MaxPermSize=256m -Djava.library.path=/home/pentaho/data-integration/../libswt/linux/x86_64/ -DKETTLE_HOME= -DKETTLE_REPOSITORY= -DKETTLE_USER= -DKETTLE_PASSWORD= -DKETTLE_PLUGIN_PACKAGES= -DKETTLE_LOG_SIZE_LIMIT= -DKETTLE_JNDI_ROOT= -jar /home/pentaho/data-integration/launcher/pentaho-application-launcher-5.2.0.0-209.jar -lib /home/pentaho/data-integration/../libswt/linux/x86_64/ -main org.pentaho.di.www.Carte carte-config.xml
java -Dorg.mortbay.util.URI.charset=UTF-8 -Xmx512m -XX:MaxPermSize=256m -Djava.library.path=/home/pentaho/data-integration/../libswt/linux/x86_64/ -DKETTLE_HOME= -DKETTLE_REPOSITORY= -DKETTLE_USER= -DKETTLE_PASSWORD= -DKETTLE_PLUGIN_PACKAGES= -DKETTLE_LOG_SIZE_LIMIT= -DKETTLE_JNDI_ROOT= -jar /home/pentaho/data-integration/launcher/pentaho-application-launcher-5.2.0.0-209.jar -lib /home/pentaho/data-integration/../libswt/linux/x86_64/ -main org.pentaho.di.www.Carte carte-config.xml

это посути та команда которая запускает carte со всеми опциями … с помощью этих данных можно настроить wrapper.
Открываем текстовым редактором файлик конфигурации conf/wrapper.conf и приводим его к такому виду:

encoding=UTF-8
wrapper.lang.folder=../lang

set.PENTAHO_DI_HOME=/home/pentaho/data-integration

wrapper.java.command=java
set.JAVA_HOME=/usr/java/jre1.7.0_67
wrapper.java.command=%JAVA_HOME%/bin/java

wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp

wrapper.java.classpath.1=%PENTAHO_DI_HOME%/launcher/pentaho-application-launcher-5.2.0.0-209.jar
wrapper.java.classpath.2=%PENTAHO_DI_HOME%/lib/*.jar

wrapper.java.library.path.1=%PENTAHO_DI_HOME%/lib
wrapper.java.library.path.2=%PENTAHO_DI_HOME%/libswt/linux/x86_64

wrapper.java.additional.auto_bits=TRUE

wrapper.java.additional.1=-Dorg.mortbay.util.URI.charset=UTF-8
wrapper.java.additional.3=-XX:MaxPermSize=256m
wrapper.java.additional.4=-Djava.library.path=%PENTAHO_DI_HOME%/libswt/linux/x86_64:%PENTAHO_DI_HOME%/lib

wrapper.java.initmemory=128

wrapper.java.maxmemory=1024

wrapper.app.parameter.1=org.pentaho.di.www.Carte
wrapper.app.parameter.2=%PENTAHO_DI_HOME%/carte-config.xml

wrapper.debug=TRUE

wrapper.console.format=PM

wrapper.console.loglevel=INFO

wrapper.logfile=../logs/wrapper.log

wrapper.logfile.format=LPTM

wrapper.logfile.loglevel=INFO

wrapper.logfile.maxsize=0

wrapper.logfile.maxfiles=0

wrapper.syslog.loglevel=NONE

wrapper.ignore_sequence_gaps=TRUE

wrapper.pidfile.strict=TRUE

wrapper.console.title=@app.long.name@

wrapper.check.deadlock=TRUE
wrapper.check.deadlock.interval=60
wrapper.check.deadlock.action=RESTART
wrapper.check.deadlock.output=FULL

wrapper.filter.trigger.1000=[Loaded java.lang.OutOfMemoryError
wrapper.filter.action.1000=NONE
wrapper.filter.trigger.1001=java.lang.OutOfMemoryError
wrapper.filter.action.1001=RESTART
wrapper.filter.message.1001=The JVM has run out of memory.

wrapper.event.jvm_restart.email.body=The JVM was restarted.\n\nPlease check on its status.\n

wrapper.name=@app.name@

wrapper.displayname=@app.long.name@

wrapper.description=@app.description@

wrapper.ntservice.dependency.1=

wrapper.ntservice.starttype=AUTO_START

wrapper.ntservice.interactive=false

Пробуем запустить, остановить приложение:

pentaho@pentahosrv:~/data-integration$ launcher/pentaho-di start
Starting Pentaho DI Server...
Waiting for Pentaho DI Server......
running: PID:532
pentaho@pentahosrv:~/data-integration$ launcher/pentaho-di stop
Stopping Pentaho DI Server...
Stopped Pentaho DI Server.
pentaho@pentahosrv:~/data-integration$

Ура! Получилось!
Также можно посмотреть статус:

pentaho@pentahosrv:~/data-integration$ launcher/pentaho-di status
Pentaho DI Server is not running.
pentaho@pentahosrv:~/data-integration$

Не запущен, запускаем и опять смотрим статус:

pentaho@pentahosrv:~/data-integration$ launcher/pentaho-di start
Starting Pentaho DI Server...
Waiting for Pentaho DI Server......
running: PID:6754
pentaho@pentahosrv:~/data-integration$ launcher/pentaho-di status
Pentaho DI Server is running: PID:6754, Wrapper:STARTED, Java:STARTED
pentaho@pentahosrv:~/data-integration$

Теперь создадим init-скрипт /etc/init.d/pentaho-di:

#!/bin/sh
### BEGIN INIT INFO
# Provides: pentaho-di
# Required-Start: network postgresql-9.3 pentaho
# Required-Stop: postgresql-9.3
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: Pentaho DI Server
### END INIT INFO

case "$1" in
"start")
  su - pentaho -c "/home/pentaho/data-integration/launcher/pentaho-di start"
  ;;
"stop")
  su - pentaho -c "/home/pentaho/data-integration/launcher/pentaho-di stop"
  ;;
"restart")
  su - pentaho -c "/home/pentaho/data-integration/launcher/pentaho-di restart"
  ;;
"status")
  su - pentaho -c "/home/pentaho/data-integration/launcher/pentaho-di status"
  ;;
*)
  echo "Usage: $0 { start | stop | restart | status }"
  ;;
esac
exit 0

Ну и добавляем его в автозагрузку:

[root@pentahosrv ~]# chkconfig --add pentaho-di
[root@pentahosrv ~]# chkconfig --list |grep pentaho
pentaho         0:off   1:off   2:on    3:on    4:on    5:on    6:off
pentaho-di      0:off   1:off   2:on    3:on    4:on    5:on    6:off
[root@pentahosrv ~]#

Теперь осталось дать права пользователю pentaho управлять сервисами. Тоесть чтобы данный пользователь мог сам перегрузить сервис не напрягая админа. Для этого в кофиге sudo /etc/sudoers добавим такую строчку:

pentaho ALL=NOPASSWD:   /sbin/service pentaho stop, /sbin/service pentaho start, /sbin/service pentaho restart, /sbin/service pentaho-di stop, /sbin/service pentaho-di start, /sbin/service pentaho-di restart, /sbin/service pentaho-di status

Теперь пользователь pentaho используя sudo сможет запустить, остановить, перезапустить 2 сервиса: pentaho и pentaho-di
Вот и все! С задачей мы справились!

Хай щастить!

  1. Комментов пока нет

  1. Трэкбэков пока нет.

Why ask?