Development Tip

Java 프로그램을 데몬 화하는 방법?

yourdevel 2020. 10. 29. 20:08
반응형

Java 프로그램을 데몬 화하는 방법?


Linux 시스템에서 데몬 화하려는 Java 프로그램이 있습니다. 즉, 쉘에서 실행을 시작하고 로그 아웃 한 후에도 계속 실행되도록하고 싶습니다. 나는 또한 프로그램을 깨끗하게 멈출 수 있기를 원합니다.

나는 트릭을 수행하기 위해 쉘 스크립팅과 자바 코드의 조합을 사용하는 이 기사발견 했다. 좋아 보이지만 가능하면 더 간단한 것을 원합니다.

Linux 시스템에서 Java 프로그램을 데몬 화하는 데 선호하는 방법은 무엇입니까?


Apache Commons Daemon 은 Java 프로그램을 Linux 데몬 또는 WinNT 서비스로 실행합니다.


다른 곳에서 인용 된 Java Service Wrapper 에 의존 할 수 없다면 (예를 들어, SW의 패키지 버전이없는 Ubuntu에서 실행중인 경우) 아마도 구식 방식으로 수행하고 싶을 것입니다. 프로그램에서 PID를 / var / run / $ progname.pid를 사용하고 표준 SysV init 스크립트를 작성합니다 (예를 들어 ntpd에 대한 스크립트를 예로 사용하면 간단합니다). 가급적이면 LSB를 준수하도록 만드십시오.

기본적으로 시작 기능은 프로그램이 이미 실행 중인지 (/var/run/$progname.pid가 존재하고 해당 파일의 내용이 실행중인 프로세스의 PID인지 테스트하여) 실행되지 않은 경우 테스트합니다.

logfile=/var/log/$progname.log
pidfile=/var/run/$progname.pid
nohup java -Dpidfile=$pidfile $jopts $mainClass </dev/null > $logfile 2>&1

중지 기능은 /var/run/$progname.pid를 검사하고, 해당 파일이 실행중인 프로세스의 PID인지 테스트하고, 해당 파일이 Java VM인지 확인합니다 (단순히 PID를 죽은 상태에서 재사용 한 프로세스를 죽이지 않도록 내 Java 데몬의 인스턴스) 다음 해당 프로세스를 종료합니다.

호출되면 내 main () 메서드는 System.getProperty ( "pidfile")에 정의 된 파일에 PID를 작성하여 시작합니다.

그러나 한 가지 주요 장애물은 Java에서 JVM이 실행되는 프로세스의 PID를 얻는 간단하고 표준적인 방법이 없다는 것입니다.

다음은 내가 생각 해낸 것입니다.

private static String getPid() {
    File proc_self = new File("/proc/self");
    if(proc_self.exists()) try {
        return proc_self.getCanonicalFile().getName();
    }
    catch(Exception e) {
        /// Continue on fall-back
    }
    File bash = new File("/bin/bash");
    if(bash.exists()) {
        ProcessBuilder pb = new ProcessBuilder("/bin/bash","-c","echo $PPID");
        try {
            Process p = pb.start();
            BufferedReader rd = new BufferedReader(new InputStreamReader(p.getInputStream()));
            return rd.readLine();
        }
        catch(IOException e) {
            return String.valueOf(Thread.currentThread().getId());
        }
    }
    // This is a cop-out to return something when we don't have BASH
    return String.valueOf(Thread.currentThread().getId());
}

다음과 같은 경우 기본적으로 다음과 같은 스크립트 나 명령 줄을 작성하는 경우가 많습니다.

  1. 한숨에 면역이되는 프로그램 실행
  2. 그것은 그것을 스폰하는 셸에서 완전히 분리됩니다.
  3. 내용도 표시되는 stderr 및 stdout에서 로그 파일을 생성하지만
  4. 진행중인 로그보기를 중지하고 실행중인 프로세스를 방해하지 않고 다른 작업을 수행 할 수 있습니다.

즐겨.

nohup java com.me.MyProgram </dev/null 2>&1 | tee logfile.log &

나는 nohup 명령을 선호합니다 . 블로그 게시물에는 더 나은 방법이 있다고 말하지만 충분하다고 생각하지 않습니다.


Java Service Wrapper를 사용해 볼 수 있습니다 . 커뮤니티 에디션은 무료이며 귀하의 요구를 충족합니다.


조건에 따라서. 일회성이라면 데몬 화 한 다음 집에 가고 싶지만 보통 결과를 기다리면 다음과 같이 할 수 있습니다.

nohup java com.me.MyProgram &

at the command line. To kill it cleanly, you have a lot of options. You might have a listener for SIGKILL, or listen on a port and shutdown when a connection is made, periodically check a file. Difference approaches have different weaknesses. If it's for use in production, I'd give it more thought, and probably throw a script into /etc/init.d that nohups it, and have a more sophisticated shutdown, such as what tomcat has.


My preferred way on Ubuntu is to use the libslack 'daemon' utility. This is what Jenkins uses on Ubuntu (which is where I got the idea.) I've used it for my Jetty-based server applications and it works well.

When you stop the daemon process it will signal the JVM to shutdown. You can execute shutdown/cleanup code at this point by registering a shutdown hook with Runtime.addShutdownHook().


This question is about daemonizing an arbitrary program (not java-specific) so some of the answers may apply to your case:


DaemonTools :- A cleaner way to manage services at UNIX https://cr.yp.to/daemontools.html

  1. Install daemon tools from the url https://cr.yp.to/daemontools/install.html follow the instruction mentioned there,for any issues please try instructions https://gist.github.com/rizkyabdilah/8516303

  2. Create a file at /etc/init/svscan.conf and add the below lines.(only required for cent-os-6.7)

 start on runlevel [12345]
 stop on runlevel [^12345]
 respawn
 exec /command/svscanboot
  1. Create a new script named run inside /service/vm/ folder and add the below lines.
#!/bin/bash    
echo starting VM 
exec java -jar
/root/learning-/daemon-java/vm.jar

Note: replace the Jar with your own Jar file. or any java class file.

  1. Reboot the system

  2. svstat / service / vm이 실행 중이어야합니다!.

  3. svc -d / service / vm은 vm을 지금 다운시켜야합니다!.
  4. svc -u / service / vm은 지금 vm을 불러 와야합니다!.

여기를보세요 :

http://jnicookbook.owsiak.org/recipe-no-022/

JNI를 기반으로하는 샘플 코드. 이 경우 자바로 시작된 코드를 데몬 화하고 메인 루프는 C에서 실행됩니다. 그러나 자바 내부에 메인, 데몬, 서비스 루프를 넣는 것도 가능합니다.

https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo029

JNI와 함께 즐기세요!


nohup java -jar {{your-jar.jar}} > /dev/null &

이것은 트릭을 할 수 있습니다.

참고 URL : https://stackoverflow.com/questions/534648/how-to-daemonize-a-java-program

반응형