Как стать автором
Обновить

Комментарии 26

Спасибо большое! Статья очень полезная.
p.s. Мне как раз на работе, в недалёком будущем, нужно будет подобную штуку реализовать! :)
НЛО прилетело и опубликовало эту надпись здесь
Можно и проще сделать.
Например так:

#include <stdlib.h>
#include <stdio.h>

int main (int argc, char** argv)
{
char* java_home = getenv(«JAVA_HOME»);

if (java_home == NULL) {
printf(«JAVA_HOME is not set! Exiting.»);
exit(1);
} else {
strcat(java_home,"/bin/java");
execv(java_home,argv);
}
}

execv перезапишет образ процесса на новый, а передавая в качестве argv[0] для нового процесса имя текущего, получим следующее

# ps ax | grep my_daemon
27061 pts/3 Sl+ 0:00 ./my_daemon test

Фактически т.е. вместо java увидим имя запускаемого executable.
НЛО прилетело и опубликовало эту надпись здесь
Обертка на shell, в данном случае все равно понадобится.

А отлов сигналов будет происходить уже средствами Java приложения, т.к. после выполнения execv никаких посредников между оберткой и JVM не будет.
Фактически — «27061 pts/3 Sl+ 0:00 ./my_daemon test» это тоже, что и «27061 pts/3 Sl+ 0:00 ./java test» только с перезаписанным argv[0].
есть готовый пакет — Apache Daemon. Только похоже забросили его делать давно
Интересно, а зачем карму-то минуснули? :)
НЛО прилетело и опубликовало эту надпись здесь
плюсанул +)
Весьма похожую штуку писали для мониторинга WLS кластеров, пока не узнали про WLST :)
Только вы забыли упомянуть, что скрипт у вас sh, а в AIX ЕМНИП ksh по дефолту (поправьте если ошибся).
Вы правы. Дефолтный там ksh, а то, что я привел — для sh/psh.
для этих целей отлично подходит Java Service Wrapper
wrapper.tanukisoftware.org

Features list:

Ability to run as a Windows Service
Ability to run as a UNIX daemon
Codeless Integration
Capture and logging of all console output from JVM
Flexible classpath configuration, including wildcards
Custom working directory
JVM Monitoring and restart functionality
Single instance enforcement
Ability to control process priority
Правда в свободной версии отсутствует server license, а покупать полную версию как-то не по нашему :).
для внутреннего использования (т.е. не для продажи) вполне хватает Community License:

While we encourage corporate and government users to make use of either a Server or Development License Agreement, the Community License Agreement is acceptable as long as the application is for internal use or will be always be distributed along with its full source.
с запуском можно былобы и несколько проще
nohup java -jar daemon.jar &

и логи в файлике на всяк случай. хотя конечно для логов надо пользовать логгеры…
По всей видимости, поле shutdownFlag в классе daemon_app надо сделать transient.
Если уж ставить, то лучше volatile.
Да, конечно volatile. Опечатался так.
извините, но начиная со строки запуска все это какой-то изврат… Почему не реализовать эту задачу на C или еще проще на perl?
Позвольте уточнить, дабы не делать поспешных умозаключений, что именно вы имеете ввиду под извратом?
Во-первых, ваша строка запуска
java daemon_app <&- 2>/var/log/daemon_app_error.log &

напоминает какое-то магическое заклинание: «Стань же демоном!» а ведь удобнее без всяких скриптов ./my_daemon и полетели, как почти всегда и бывает в мире unix.
Во-вторых, я не увидел в вашем способе установки обработчика привязки конкретно к сигналу SIGTERM. А как мне установить обработчик на SIGHUP и перечитать конфигурационный файл?
В-третьих, вы делаете процесс демоном с помощью механизма управления заданиями, который, между прочим, поддерживают не все оболочки, но хуже всего то, что ваш процесс по-прежнему находится в одной сессии с процессом командной оболочки и связан с управляющим терминалом со всеми вытекающими.
Мон пардон, ни разу не специалист в этом, но разве в функции check_classpath в строчке if [ ${#resource} -gt 0 ] && [! -r $resource ] не должен быть оператор «или» вместо «и»?
[ ${#resource} -gt 0 ] проверяет длину элемента в classpath
[! -r $resource ] — проверяет или элемент доступен для чтения

условие должно быть тут именно «и».

Ведь элементы с нулевой длинной нас не интересуют. Нам нужно проверить те элементы, которые указаны в classpath и не существуют или для чтения которых у нас не достаточно прав.

Если хотя бы одно из условий не выполнится, будет отражено предупреждение.
Да, понял когда уже коммент отправил :) Мне сначала подумалось, что ${#resource} -gt 0 проверяет файловый дескриптор, а не строку. Прошу прощения, как уже говорил, совсем не специалист в шелл-скриптах :)
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.