Apache Daemon 에 대해서

2015. 12. 8. 10:03Java

사내에서 사용하는 Apache Deamon에 대해서 정리를 해본다.

아래 링크에 있는 내용을 번역을 해봤습니다.


Introduction
1994년 이후에, 자바 프로그램은 클라이언트와의 통신을 하는 서버 어플리케이션을 개발하는 대표적인 도구로써 자리 매김하였습니다.
하지만, 단점으로 아직까지도 Entry의 싱글 포인트에 의존하는 자바 어플리케이션를 시작하기 위한 유일한 portable 방법이라는 것입니다.
Single Point of Entry (the public static void main(String[]) method)

클라이언트 어플리케이션에서는 Single Point of Entry 는 사용자가 클라이언트간에 양방향으로 종료 명령 메소드를 호출할 수 있는 효과적인 솔루션이죠.
종료 명령 : System.exit(int) 메소드를 호출하는 것에 의해 가상머신 프로세스를 종료 할수 있는 것
하지만, 서버 어플리케이션은 가상머신의 즉각적인 셧다운을 알아낼수 있는 어떠한 Portable 방법이 없습니다. 다시 말해 양방향이 아니란 이야기죠.

자바로 작성된 서버 어플리케이션은 가상머신 프로세스가 셧다운 되어지 전에, 몇몇 테스크가 작동되어야 할 지도 모릅니다.
예를 들면, 서블릿 컨테이너 경우, 가상머신 프로세스가 셧다운 되기 전에, 해당 세션들이 디스크에 serialize 되어야 할 필요가 있을 수도 있고,
웹 어플리케이션은 소멸되어야 하는 것도 필요할 것입니다.

이런 문제에 대한 한가지 공통적인 방법은 ServerSocket를 생성해서, 해당 이슈가 있는 특정 메세지를 기다리는 것이죠.
메세지를 전달 받을 때면, 서버 어플리케이션이 셧다운 되기 전에, 필요로한 동작들이 선행되고, 이후에 가상 머신 프로세스가 종료 되도록 
System.exit 메소드가 호출됩니다.

 - 넓은 범위의 시스템 셧다운과 같은 경우, OS에 의해 동작하는 서버 어플리케이션에 어떠한 노티가 없이 가상머신 프로세스는 즉시 셧다운 됩니다.
 - 크래커들이 서버로 보내는 위의 메세지 들 중에 셧다운 메세지를 찾아 낸다면, 그리고 이 메세지를 보내는 방법을 찾아낸다면 , OS상의 모든 보안 제약을 구현해 놓은 것을 우회 해서, 쉽게 서버의 동작을 방해 할수 있겠죠.

대부분의 멀티 유저 OS은 서버 어플리케이션을 시작하고 종료하는 방법을 가지고 있습니다.
유닉스 기반의 OS는 deamons 이라고 불리는 논 인터렉티브 서버 어플리케이션, 특정한 신호 셋을 가지고 OS에 의해 조종되어 집니다.
윈도우즈 기반의 OS에서는 그런 프로그램들을 Services 라고 불리고, 어플리케이션 바이너리에 정의되어진 특정 함수들의 appropriate calls에 의해 조종되어 집니다.
하지만, 비록 프로그램을  두가지 경우의 OS하에서 다루는 방법들이 다르더라도, 그것들의 즉각적인 셧다운상의 서버 어플리케이션을 알아차릴수 있고,
그것의 프로세스 능력이 소멸되어기 전에 어플리케이션은  확실한 업무를 동작시킬수 있는 능력을 가지고 있습니다. 

Structure

Deamon은 두 부분으로 만들어 졌습니다.
하나는 OS상의 인터페이스를 만든  C로 작성되어 졌고, Deamon API를 제공하는 Java로 하나는 작성되었답니다.

Platform

Win32 와 Unix 과 같은 플랫폼들 모두 지원합니다. 
Win32 플랫폼은 procrun 을 사용합니다.  Unix와 같은 플랫폼은 jsvc를 사용합니다.

Initial Source of the Package

원본 자바 클래스들은 Jakarta Tomcat 4.0 project로 부터 왔습니다.
Deamon component의 패키지명은 org.apache.commons.deamon 입니다. 


데몬과 백그라운드 프로그램의 차이는 터미널을 가지고 있지 않냐? 아니면, 가지고 있느냐에 차이입니다.


그럼 서버상에 "jsvc"를 설치 

1. 심호흡을 하십시다. 그리고 서버로 들어가요
2. 폴더를 만들어 보아요
     mkdir /root/commons-daemon
     cd /root/commons-daemon
3. 다운로드 받아라
     wget http://www.apache.org/dist/commons/daemon/binaries/commons-daemon-1.0.15.jar
4.  압축을 풀고 들어가라.
     tar zxvf commons-daemon-1.0.15-native-src.tar.gz
     cd commons-daemon-1.0.15-native-src/unix
5. 컴파일 하십시요
     sh support/buildconf.sh
     ./configure --with-java=/java위치  (./configure --with-java=/etc/alternatives/jre_1.8.0)
     make
     mv jsvc /root/commons-deamon


*중간에 하다가 막혀서 설치한거
1.  "$'\r': command not found" 와 같이 윈도우에서 쉘 만들어 유닉스 상에서 실행 하다보면, ㅎㅎㅎ
dos2unix 설치 합니다. : yum install dos2unix 
   dos2unix  A.sh B.sh
2. "no acceptable C compiler found in $PATH"라는 에러가 발생
autoconf 를 설치 합니다. : yum install autoconf
설치 전 확인 : rpm -qa | grep ^gcc
설치 : yum -y install gcc 


DeamonBox 라는 프로젝트를 생성했습니다.

- maven 기반으로 프로젝트로 생성 했는데요?

1. Deamon 인터페이스를 구현하면 된다.
     또한 스레드로 실행되어야 하므로, Runnable 도 구현 해야 한다.
     만약 스레드로 구동하지 않는 경우, 종료 처리가 제대로 되지 않고,
     "Service exit with a return value of 143" 오류 발생

2. 1초마다 숫자를 하나씩 증가시키면서 찍는 프로그램을 만든다.

public class DaemonMain implements Daemon,Runnable {

    private String status "";
    private int increasingNumber 0;
    private Thread thread null;


    public void init(DaemonContext context) throws DaemonInitExceptionException {
        System.out.println("init.........");
        String[] args = context.getArguments();
        if(args != null){
            for(String arg: args){
                System.out.println(arg);
            }
        }
        status "INITED";
        this.thread new Thread(this);
        System.out.println("init OK");
        System.out.println();
    }

    public void start() throws Exception {
        System.out.println("status: " status);
        System.out.println("start...");
        status "STARTED";
        this.thread.start();
        System.out.println("start OK.");
        System.out.println();
    }

    public void stop() throws Exception {
        System.out.println("status: " status);
        System.out.println("stop...");
        status "STOPED";
        this.thread.join(10);
        System.out.println("stop OK.");
        System.out.println();
    }


    public void destroy() {
        System.out.println("status: " status);
        System.out.println("destroy...");
        status "DESTROIED";
        System.out.println("destroy OK.");
        System.out.println();
    }


    public void run() {
        while (true){
            System.out.println(increasingNumber);
            try{
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }

            if(increasingNumber 1000){
                break;
            }
            increasingNumber++;
        }
    }
}


3. 이제 이 Deamon 프로그램을 실행할 Shell Script를 작성한다. 
     (common-deamon-1.0.15-src/src/samples/ServiceDeamon.sh 를 참고하세요)

#!/bin/sh
JAVA_HOME=/usr/java/jdk1.8.0_65/
JSVC=/root/commons-daemon/jsvc
USER=root

DAEMON_HOME=/root/commons-daemon
PID_FILE=$DAEMON_HOME/daemon.pid
OUT_FILE=$DAEMON_HOME/daemon.out
#ERR_FILE=$DEAMON_HOME/deamon.err

CLASSPATH=$DAEMON_HOME/commons-daemon-1.0.15.jar:$DAEMON_HOME/daemon-1.0-SNAPSHOT.jar

MAIN_CLASS=com.ksh.daemon.DaemonMain

case "$1" in
        start)
        #
        # Start Deamon
        #
        rm -f $OUT_FILE
        $JSVC   \
        -user $USER     \
        -java-home      $JAVA_HOME      \
        -pidfile        $PID_FILE       \
        -outfile        $OUT_FILE       \
        -errfile        $OUT_FILE       \
        -cp     $CLASSPATH      \
        $MAIN_CLASS

        exit $?
        ;;

        stop)
        #
        # Stop Daemon
        #
        $JSVC   \
        -stop   \
        -nodetach       \
        -java-home      $JAVA_HOME      \
        -pidfile        $PID_FILE       \
        -outfile        $OUT_FILE       \
        -errfile        $OUT_FILE       \
        -cp     $CLASSPATH      \
        $MAIN_CLASS
        exit $?
        ;;

        *)

        echo "[Usage] TestDaemon.sh start | stop"
        exit 1;;
esac


 4. 실행과 종료를 해본다.
실행 : /root/commons-deamon/TestDeamon.sh start
종료 : /root/commons-deamon/TestDeamon.sh stop


5. deamon.out 의 내용을 확인



경로 확인 잘 하면 위와 같이 잘 됩니다. 


'Java' 카테고리의 다른 글

core java 따라하기 - 2  (0) 2017.06.15
core java 따라하기 - 1  (0) 2017.06.13
JUnit5 개념 잡기  (0) 2017.06.02
java8 StringJoiner 과 String.join 활용  (0) 2016.01.05
ThreadLocal 이 뭘까요?  (0) 2016.01.05
Runtime.addShutdownHook()  (0) 2015.09.30
Top 10 Useful, Yet paranoid Java Programming Techniques  (0) 2015.09.15
Exception  (0) 2013.08.04
Regular Expressions in Java  (0) 2013.07.30
Delegate, Event , Ramda  (0) 2013.07.04