What is daemon process in java

Создание демон-процесса на Java

Недавно, по долгу службы, появилась необходимость написать background process для IBM AIX 5.2 на Java с контролирующим shell скриптом.

Раз работа проделана, документация поднята, код написан, почему бы не поделиться с общественностью? По сему, переходим к делу.

1 Демонизация

  1. Отключить stdin от терминала
  2. Запустить процесс в background’e путем указания амперсанда «&» в конце строки запуска
  3. Закрыть stdin, stdout непосредственно в приложении (в нашем случае, для Java, это будет System.in.close(); System.out.close();)

где » «&» как и говорилось, позволит перевести работу приложения из foreground в background режим.

Код daemon_app должен выглядеть приблизительно следующим образом:

public class daemon_app < public static int main(String[] args) < try < daemonize(); >catch (Throwable e) < System.err.println("Startup failed. " + e.getMessage()); return 1; >doProcessing(); return 0; > static private void daemonize() throws Exception < System.in.close(); System.out.close(); >static private void doProcessing() < //Do some processing >>

Метод daemonize отключает приложение от stdin и stdout. Единым активным остается поток stderr, который мы можем использовать для логирования ошибок на стадии инициализации.

Метод doProcessing предназначен для реализации основной логики.

Далее мы можем использовать какой-либо фреймворк для логирования, например log4j.

Следующим усовершенствованием будет изменение строки запуска для перехвата данных отправленных нашим процессом в stderr. Для этого, модифицируем строку запуска следующим образом:

java daemon_app /var/log/daemon_app_error.log &

где «2>/var/log/daemon_app_error.log» перенаправит вывод с stderr в файл /var/log/daemon_app_error.log.

Если читатель не в курсе, то потоки ввода-вывода в unix shell имеют следующие идентификаторы:

stdin – 0
stdout – 1
stderr – 2

2 Организация обработки сигналов прерывания

В методе doProcessing мы можем организовать бесконечный цикл с предусловием, по которому будет осуществляться окончание работы процесса. Таким условием может быть SIGTERM отправленный из операционной системы, например, посредством kill -15 .

Код 15 (SIGTERM) одинаков как для AIX, HP-UX так и для обычной Linux-based системы.
Список сигналов и их кодов можно получить с помощью команды kill -l.

  • Использование sun.misc.Signal и sun.misc.SignalHandler с последующим созданием собственного класса-обработчика, который имплементирует sun.misc.SignalHandler. Более детальную информацию по данному методу вы можете найти тут (http://www.ibm.com/developerworks/ibm/library/i-signalhandling/)
  • Использование метода Runtime.getRuntime().addShutdownHook. (сигнатура метода: public void addShutdownHook(Thread hook))

Вот, что Sun пишет (http://java.sun.com/products/jdk/faq/faq-sun-packages.html) про package sun.*:

The sun.* packages are not part of the supported, public interface.
A Java program that directly calls into sun.* packages is not guaranteed to work on all Java-compatible platforms. In fact, such a program is not guaranteed to work even in future versions on the same platform…

2-й метод предусматривает передачу в него в качестве аргумента класс наследованный от Thread. Это значит, что при получении SIGTERM будет создан новый thread, который будет совершать определенные программистом действия для завершения работы процесса в целом.

Обратимся к документации (http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#19152), какие же предусловия необходимы, для завершения работы Java программы?

  • All the threads that are not daemon threads (§2.19) terminate.
  • Some thread invokes the exit method of class Runtime or class System, and the exit operation is permitted by the security manager.
  1. Если у нас есть запущенные не демон-нити, необходимо обеспечить их корректное завершение и присоединить их к main, используя join. Демон-thread’ы, т.е. те, для которых было выполнено setDaemon(true), останавливать не обязательно.
  2. Остановить работу thread main, что подразумевает выход из main метода запускаемого класса.
Читайте также:  Setting timezone javascript date

Модифицированный код с использованием Runtime.getRuntime().addShutdownHook для создания обработчика сигналов прерывания приведен ниже:

public class daemon_app < static private boolean shutdownFlag = false; public static int main(String[] args) < try < daemonize(); >catch (Throwable e) < System.err.println("Startup failed. " + e.getMessage()); return 1; >registerShutdownHook(); doProcessing(); return 0; > static private void doProcessing() < while (false == shutdownFlag) < //Do some processing >> static public void setShutdownFlag() private static void registerShutdownHook() < Runtime.getRuntime().addShutdownHook( new Thread() < public void run() < daemon_app.setShutdownFlag(); >> ); > static private void daemonize() throws Exception < System.in.close(); System.out.close(); >>

Итак, мы имеем метод registerShutdownHook, который вызывается из main и регистрирует обработчик на сигнал прерывания.

При получении сигнала прерывания, вызывается статический метод setShutdownFlag, который меняет значение статического булевого свойства shutdownFlag на true, по значению которого организован цикл в методе doProcessing с предусловием.

3 Контроллирующий скрипт

Итак, процесс-демон написан. Теперь необходимо создать скрипт управляющий его запуском, остановкой и мониторингом состояния.

Описывать весь процесс создания shell control скрипта я не буду, приведу только несколько полезных процедур.

Пример проверки переменных окружения необходымых для запуска/работы процесса

Процедура без аргументов. Перебираем необходимые переменные окружения циклом for. Если переменной нет, выводим предупреждение. Если хотя бы одна переменная не установлена, прекращаем выполнение с кодом ошибки 1.

Проверка элементов classpath

Аргументом этой процедуры является строка с classpath, в котором элементы отделены двоеточием.
Заменяем двоеточие пробельным символом — в результате получаем возможность проверить каждый элемент.

check_classpath() < #Checking files in classpath are exists and readable for resource in `echo $1 | sed -e "s/:/ /g"`; do if [ $-gt 0 ] && [ ! -r $resource ] # if file not exists or not readable then echo "WARNING: Resource '$resource' included in CLASSPATH does not exist or not readable" fi done >
Пример процедуры запуска процесса

Данная процедура предусматривает наличие установленных переменных — PID_DIR, PROCESS_NAME, CPATH

PID_DIR – директория для хранения pid файлов
PROCESS_NAME — имя процесса
CPATH — строка с classpath

Идентификатор процесса запущенного в background’е, можно определить с помощью shell-переменной «$!», который впоследствии записывается в pid файл.

После чего происходит проверка на протяжении 5 секунд, или процесс «не упал» в процессе запуска. Каждую секунду происходит проверка с помощью ps -p статус процесса.

launch_daemon() < JVM_OPTS="" # Set max memory to 1G JVM_OPTS="$JVM_OPTS -Xmx1G" echo "Starting process \c" # Run process in background with closed input stream, to detach it from terminal $JAVA_HOME/bin/java $JVM_OPTS -cp $CPATH daemon_app /var/log/$PROCESS_NAME.pid & #Write pid to pid file echo $! > $PID_DIR/$PROCESS_NAME.pid if [ $ -eq 0 ] then echo ". [ failed ]" else # Checking for 5 seconds if process is alive timer=0 while [ $timer -lt 6 ] do echo ".\c" sleep 1 timer=$timer+1 done if [ `ps -p $! | wc -l` -gt 1 ] then echo " [ started ]" exit 0 else echo " [ failed ]" exit 1 fi fi >
Пример процедуры остановки процесса
Пример процедуры проверки статуса процесса

Принимает 1 аргумент — абсолютный путь к pid файлу

Возвращает значение отличное от 0, если процесс запущен и работает, 0 — если процесс неактивен.

check_running() < if [ -e $1 ] then fpid=`cat $1` if [ $-gt 0 ] then lines=`ps -p $fpid | wc -l` echo $(($lines-1)) else echo 0 fi else echo 0 fi >

Вот в принципе и все, что хотел рассказать.

Интересно услышать, кто что думает на эту тему.

Источник

Difference Between Daemon Threads and User Threads In Java

Daemon threads are low priority threads which always run in background and user threads are high priority threads which always run in foreground. User Thread or Non-Daemon are designed to do specific or complex task where as daemon threads are used to perform supporting tasks.

Читайте также:  J Logo

Difference Between Daemon Threads And User Threads In Java

  1. JVM doesn’t wait for daemon thread to finish but it waits for User Thread : First and foremost difference between daemon and user threads is that JVM will not wait for daemon thread to finish its task but it will wait for any active user thread. For example, one might have noticed this behavior while running Java program in NetBeans that even if the main thread has finished, the top left down button is still red, showing that Java program is still running. This is due to any user thread spawned from the main thread, but with main thread one don’t see that red dot in NetBeans.
  2. Thread Priority : The User threads are high priority as compare to daemon thread means they won’t get CPU as easily as a user thread can get.
  3. Creation of Thread : User thread is usually created by the application for executing some task concurrently. On the other hand, daemon thread is mostly created by JVM like for some garbage collection job.
  4. Termination of Thread : JVM will force daemon thread to terminate if all user threads have finished their execution but The user thread is closed by application or by itself. A user thread can keep running by the JVM running but a daemon thread cannot keep running by the JVM. This is the most critical difference between user thread and daemon thread.
  5. Usage : The daemons threads are not used for any critical task. Any important task is done by user thread. A daemon thread is generally used for some background tasks which are not critical task.

The Major Difference between User and Daemon Threads:

User Thread Daemon Thread
JVM wait until user threads to finish their work. It never exit until all user threads finish their work. The JVM will’t wait for daemon threads to finish their work. The JVM will exit as soon as all user threads finish their work.
JVM will not force to user threads for terminating, so JVM will wait for user threads to terminate themselves. If all user threads have finished their work JVM will force the daemon threads to terminate
User threads are created by the application. Mostly Daemon threads created by the JVM.
Mainly user threads are designed to do some specific task. Daemon threads are design as to support the user threads.
User threads are foreground threads. Daemon threads are background threads.
User threads are high priority threads. Daemon threads are low priority threads.
Its life independent. Its life depends on user threads.

Example: Check Thread is Daemon or not One can make a user thread as daemon thread by using setDaemon(boolean) method. In this example, thread type is being checked (User thread or Daemon thread) by using isDaemon() method. It returns true if it is daemon otherwise it returns false.

Источник

Читайте также:  Ajax PHP MySQL Search Example

What is daemon process in java

ApacheCon

Introduction

Since 1994, the Java programming language evolved and became a valid tool to develop reliable and performant server applications as opposed to just applets and client applications. The major disadvantage of the Java platform is that still today the only portable way to start a Java application relies on a single point of entry: the public static void main(String[]) method.

Having a single-point of entry is a valid solution for client applications, where interactively a user can command to the application to quit (which can terminate the Virtual Machine process at calling the System.exit(int) method), but in those cases where the application is not interactive (server applications) there is currently no portable way to notify the Virtual Machine of its imminent shutdown.

A server application written in Java might have to perform several tasks before being able to shut down the Virtual Machine process. For example in the case of a Servlet container, before the VM process is shut down, sessions might need to be serialized to disk, and web applications need to be destroyed.

One common solution to this problem is to create (for example) a ServerSocket and wait for a particular message to be issued. When the message is received, all operations required to shut down the server applications are performed and at the end the System.exit method is called to terminate the Virtual Machine process. This method however, has several disadvantages and risks:

  • In case of a system-wide shutdown, the Virtual Machine process may be shut down directly by the operating system without notifying the running server application.
  • If an attacker finds out the shutdown message to send to the server and discovers a way to send this message, he can easily interrupt the server’s operation, bypassing all the security restrictions implemented in the operating system.

Most multi-user operating systems already have a way in which server applications are started and stopped. Under Unix based operating systems non-interactive server applications are called daemons and are controlled by the operating system with a set of specified signals. Under Windows such programs are called services and are controlled by appropriate calls to specific functions defined in the application binary, but although the ways of dealing with the problem are different, in both cases the operating system can notify a server application of its imminent shutdown, and the application has the ability to perform certain tasks before its process of execution is destroyed.

Structure

Daemon is made of 2 parts. One written in C that makes the interface to the operating system and the other in Java that provides the Daemon API.

Platforms

Both Win32 and UNIX like platforms are supported. For Win32 platforms use procrun. For UNIX like platforms use jsvc.

Initial Source of the Package

The original Java classes came from the Jakarta Tomcat 4.0 project.

The package name for the Daemon component is org.apache.commons.daemon .

Copyright © 2002-2023 The Apache Software Foundation. All Rights Reserved.

Apache Commons, Apache Commons Daemon, Apache, the Apache feather logo, and the Apache Commons project logos are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners.

Источник

Оцените статью