Java 프로세스를 정상적으로 정지하는 방법
Linux 및 Windows에서 Java 프로세스를 정상적으로 중지하려면 어떻게 해야 합니까?
언제?Runtime.getRuntime().addShutdownHook
전화받고 언제 안 받죠?
파이널라이저는요? 도움이 되나요?
셸에서 Java 프로세스로 신호를 보낼 수 있습니까?
휴대성이 좋은 솔루션을 찾고 있습니다.
셧다운 후크는 VM이 강제로 중지되지 않은 모든 경우에 실행됩니다.그래서 만약 당신이 "표준" 킬을 발행한다면SIGTERM
명령어를 실행한다.마찬가지로 콜 후에 실행됩니다.System.exit(int)
.
하지만 힘든 살생(kill -9
또는kill -SIGKILL
실행하지 않습니다.마찬가지로 컴퓨터의 전원을 끄거나, 끓는 용암통에 떨어뜨리거나, CPU를 큰 망치로 두들겨 부수면(그리고 명백하게) 실행되지 않습니다.하지만 당신은 이미 알고 있었을 겁니다.
파이널라이저도 실제로 실행되어야 하지만 셧다운 청소에 의존하지 말고 셧다운 후크에 의존하여 작업을 완전히 중단하는 것이 좋습니다.그리고 항상 그렇듯이 교착 상태에 주의해야 합니다(전체 프로세스에 너무 많은 셧다운 훅이 걸려 있는 것을 보았습니다).
네, 'Java Monitoring and Management'와 협력하기로 선택한 모든 가능성에도 불구하고
개요는 이쪽
이것에 의해, 어느 애플리케이션을 다른 애플리케이션으로부터 비교적 간단하게 제어할 수 있습니다.스크립트에서 제어 애플리케이션을 호출하여 제어된 애플리케이션을 종료하기 전에 정상적으로 중지할 수 있습니다.
다음은 간단한 코드입니다.
제어된 응용 프로그램:
다음 VM 매개 변수를 사용하여 실행합니다.
- DCOM.sun.management.jmxremote
- DCOM.sun.management.jmxremote.포트=9999
- DCOM.sun.management.jmxremote.authenticate=false
- DCOM.sun.management.jmxremote.ssl=false
//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");
}
}
}
응용 프로그램 제어:
명령줄 인수로 stop 또는 start를 사용하여 실행합니다.
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();
}
}
}
이상입니다. :-)
다른 방법으로는 응용 프로그램이 서버 socet을 열고 정보가 도착할 때까지 기다릴 수 있습니다.예를 들어, "magic" 워드를 가진 문자열이 셧다운되도록 응답합니다.System.exit().이러한 정보는 telnet 등의 외부 애플리케이션을 사용하여 socke로 전송할 수 있습니다.
조금 까다롭지만 휴대성이 뛰어난 솔루션을 소개합니다.
자바 에이전트를 구현했습니다.Github: https://github.com/everit-org/javaagent-shutdown 에서 구할 수 있습니다.
솔루션의 상세한 것에 대하여는, https://everitorg.wordpress.com/2016/06/15/shutting-down-a-jvm-process/ 를 참조해 주세요.
여기서도 같은 질문입니다.
Java의 피니셔는 불량입니다.쓰레기 수거에 많은 오버헤드를 더합니다.가능하면 피하세요.
셧다운후크는 VM이 종료될 때만 호출됩니다.당신이 원하는 대로 잘 할 수 있을 것 같아요.
Linux 에서의 시그널링은 "kill"(사용 가능한 신호에 대한 man kill)로 실행할 수 있습니다.그렇게 하려면 프로세스 ID(ps ax | grep java) 등이 필요합니다.프로세스가 작성되었을 때 프로세스 ID를 저장합니다(대부분의 Linux 스타트업 파일에 사용됩니다./etc/initd 참조).
휴대용 시그널링은 Java 응용 프로그램에 SocketServer를 통합함으로써 실행할 수 있습니다.그렇게 어렵지 않고 원하는 명령어를 자유롭게 보낼 수 있습니다.
finalizer가 아닌 finalizer를 의미하는 경우 System.exit()가 호출될 때 구가 extecut되지 않습니다.파이널라이저는 동작하지만 디버깅스테이트먼트를 인쇄하는 것 이외에는 의미가 없습니다.그들은 위험합니다.
답변 감사합니다.셧다운 훅이 제 경우처럼 이음새에 잘 맞습니다.그런데 '모니터링과 관리 콩'이라는 것도 우연히 만났어요.
http://java.sun.com/j2se/1.5.0/docs/guide/management/overview.htmlhttpjava.sun.com/j2se/1.5.0/docs/guide//overview.html
및 프로세스의 몇 가지 수 5Java는 Java 프로세스를 조작할 수 있습니다.
언급URL : https://stackoverflow.com/questions/191215/how-to-stop-java-process-gracefully
'source' 카테고리의 다른 글
플랫폼에 의존하는 새로운 행 문자를 얻으려면 어떻게 해야 하나요? (0) | 2022.11.24 |
---|---|
Larabel이 피벗 테이블에 여러 레코드를 추가하지 않음 (0) | 2022.11.24 |
python의 현재 시간에 시간을 추가하는 방법 (0) | 2022.11.24 |
jQuery를 사용하여 목록을 알파벳 순으로 정렬하려면 어떻게 해야 합니까? (0) | 2022.11.24 |
"package private" 멤버액세스는 디폴트(수정자 없음)액세스와 동의어 아닌가요? (0) | 2022.11.24 |