IT

Java 프로세스를 중지하는 방법은 무엇입니까?

lottoking 2020. 9. 14. 21:25
반응형

Java 프로세스를 중지하는 방법은 무엇입니까?


Linux 및 Windows에서 Java 프로세스를 중지하려는 방법?

언제 Runtime.getRuntime().addShutdownHook전화를 받고 언제 전화를 받았습니까?

파이널 라이저는 어떻습니까? 여기서 도움이 검증?

쉘에서 Java 프로세스로 사용 가능한 신호를 보낼 수 있습니까?

선호하는 솔루션을 찾고 있습니다.


종료 후크는 VM이 ​​강제로 종료되지 않은 경우 실행됩니다. 따라서 "표준"kill ( SIGTERMkill 명령에서)을 실행하면 실행됩니다. 검증을 호출 한 후에 실행 System.exit(int)됩니다.

그러나 하드 하드 킬 ( kill -9또는 kill -SIGKILL)은 실행되지 않습니다. 유사하게 (그리고 분명히) 컴퓨터에서 전원을 끌어 내거나 끓는 용암 통에 넣거나 큰 망치로 CPU를 조각 내면 실행되지 않음. 그래도 이미 알고있을 것입니다.

종료 자도 실행되어야하지만 종료 정리에 의존하는 것이 아니라 종료 후크에 의존하여 작업을 중지하는 것이 가장 좋습니다. 그리고 항상 그렇듯이 교착 상태에주의하십시오 (너무 많은 종료 후크가 전체 프로세스를 중단시키는 것을 보았습니다)!


좋아, 내가 "자바 모니터링 및 관리"로 작업하기로 선택한 가능성
이 여기에있다.
이것은 쉬운 방법으로 하나의 응용 프로그램을 다른 응용 프로그램에서 제어 할 수있게 해요. 펼쳐서 제어 애플리케이션을 호출하여 제어 애플리케이션을 종료하기 전에 중지 할 수 있습니다.

다음은 간단한 코드입니다.

제어 된 응용 프로그램 :
다음 VM 매개 변수를 사용하여 실행합니다.
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port = 9999
-Dcom.sun.management.jmxremote.authenticate = false
-Dcom.sun.management. jmxremote.ssl = 거짓

//ThreadMonitorMBean.java
public interface ThreadMonitorMBean
{
String getName();
void start();
void stop();
boolean isRunning();
}

// ThreadMonitor.java
public class ThreadMonitor implements ThreadMonitorMBean
{
private Thread m_thrd = null;

public ThreadMonitor(Thread thrd)
{
    m_thrd = thrd;
}

@Override
public String getName()
{
    return "JMX Controlled App";
}

@Override
public void start()
{
    // TODO: start application here
    System.out.println("remote start called");
}

@Override
public void stop()
{
    // TODO: stop application here
    System.out.println("remote stop called");

    m_thrd.interrupt();
}

public boolean isRunning()
{
    return Thread.currentThread().isAlive();
}

public static void main(String[] args)
{
    try
    {
        System.out.println("JMX started");

        ThreadMonitorMBean monitor = new ThreadMonitor(Thread.currentThread());

        MBeanServer server = ManagementFactory.getPlatformMBeanServer();

        ObjectName name = new ObjectName("com.example:type=ThreadMonitor");

        server.registerMBean(monitor, name);

        while(!Thread.interrupted())
        {
            // loop until interrupted
            System.out.println(".");
            try 
            {
                Thread.sleep(1000);
            } 
            catch(InterruptedException ex) 
            {
                Thread.currentThread().interrupt();
            }
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    finally
    {
        // TODO: some final clean up could be here also
        System.out.println("JMX stopped");
    }
}
}

응용 프로그램을 제어 :
으로 실행 중지 하거나 시작 명령 행 인수로

public class ThreadMonitorConsole
{

public static void main(String[] args)
{
    try
    {   
        // connecting to JMX
        System.out.println("Connect to JMX service.");
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:9999/jmxrmi");
        JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
        MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

        // Construct proxy for the the MBean object
        ObjectName mbeanName = new ObjectName("com.example:type=ThreadMonitor");
        ThreadMonitorMBean mbeanProxy = JMX.newMBeanProxy(mbsc, mbeanName, ThreadMonitorMBean.class, true);

        System.out.println("Connected to: "+mbeanProxy.getName()+", the app is "+(mbeanProxy.isRunning() ? "" : "not ")+"running");

        // parse command line arguments
        if(args[0].equalsIgnoreCase("start"))
        {
            System.out.println("Invoke \"start\" method");
            mbeanProxy.start();
        }
        else if(args[0].equalsIgnoreCase("stop"))
        {
            System.out.println("Invoke \"stop\" method");
            mbeanProxy.stop();
        }

        // clean up and exit
        jmxc.close();
        System.out.println("Done.");    
    }
    catch(Exception e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}


그게 다야. :-)


다른 방법 : 애플리케이션이 서버 소스를 열고 정보가 도착할 때까지 기다릴 수 있습니다. 예를 들어 "마법의"단어가있는 문자열 :) 그리고 나서 시스템을 종료하기 위해 반응합니다 : System.exit (). 텔넷과 같은 외부 응용 프로그램을 사용하여 이러한 정보를 socke에 보낼 수 있습니다.


여기에 비슷한 질문

Java의 종료자는 잘못되었습니다. 가비지 수집에 많은 오버 헤드를 추가합니다. 가능한 한 피하십시오.

shutdownHook은 VM이 종료 될 때만 호출됩니다. 나는 그것이 당신이 원하는 것을 아주 잘 할 것이라고 생각합니다.


다음은 약간 까다 롭지 만 이식 가능한 솔루션입니다.

  • 애플리케이션에서 종료 후크 구현
  • JVM을 정상적으로 종료 하려면 Attach API를 사용하여 System.exit ()호출 하는 Java 에이전트설치하십시오 .

Java Agent를 구현했습니다. Github에서 사용할 수 있습니다 : https://github.com/everit-org/javaagent-shutdown

솔루션에 대한 자세한 설명은 https://everitorg.wordpress.com/2016/06/15/shutting-down-a-jvm-process/에서 확인할 수 있습니다.


Linux에서 시그널링은 "kill"(사용 가능한 시그널에 대한 man kill)로 수행 할 수 있습니다.이를 수행하려면 프로세스 ID가 필요합니다. (ps ax | grep java) 또는 이와 유사한 것 또는 프로세스가 생성 될 때 프로세스 ID를 저장합니다 (대부분의 Linux 시작 파일에서 사용됨, /etc/init.d 참조).

이식 가능한 신호는 Java 애플리케이션에 SocketServer를 통합하여 수행 할 수 있습니다. 그렇게 어렵지 않으며 원하는 명령을 자유롭게 보낼 수 있습니다.

종료 자 대신 finally 절을 의미했다면; System.exit ()가 호출 될 때 실행되지 않습니다. 종료자는 작동해야하지만 실제로 더 중요한 작업을 수행해서는 안되지만 디버그 문을 인쇄해야합니다. 위험합니다.


답변 해 주셔서 감사합니다. Shutdown은 내 경우에 작동하는 것과 같은 이음새를 연결합니다. 그러나 나는 또한 Monitoring and Management Bean이라는 것에 부딪 혔습니다.
http://java.sun.com/j2se/1.5.0/docs/guide/management/overview.html
원격 모니터링과 조작을위한 좋은 가능성을 제공합니다. 자바 프로세스의. (Java 5에서 도입 됨)

참고 URL : https://stackoverflow.com/questions/191215/how-to-stop-java-process-gracefully

반응형