如何在Linux和Windows中優雅地停止Java進程?如何優雅地停止java進程?
Runtime.getRuntime().addShutdownHook
何時被調用,什麼時候不調用?
終結者怎麼樣,他們在這裏幫助嗎?
我可以從shell發送某種信號給Java進程嗎?
我在尋找最好的便攜式解決方案。
如何在Linux和Windows中優雅地停止Java進程?如何優雅地停止java進程?
Runtime.getRuntime().addShutdownHook
何時被調用,什麼時候不調用?
終結者怎麼樣,他們在這裏幫助嗎?
我可以從shell發送某種信號給Java進程嗎?
我在尋找最好的便攜式解決方案。
關閉掛鉤在虛擬機未被強行殺死的所有情況下執行。因此,如果您要發出「標準」殺死(kill命令中的SIGTERM
),那麼它們將執行。同樣,他們將在致電System.exit(int)
後執行。
但是一個硬殺(kill -9
或kill -SIGKILL
),那麼他們將不會執行。同樣的(顯然),如果你從計算機中取出電源,將它放入沸騰的熔岩桶中,或者用大錘擊碎CPU,它們將不會執行。不過,你可能已經知道了。
終結器真的應該運行,但最好不要依賴於關閉清理,而是依靠你的關閉鉤子乾淨地停止事情。和往常一樣,要小心死鎖(我已經看到太多的關機掛鉤掛在整個過程中)!
在關機的情況下,您是否閱讀過javadoc?在Linux中
https://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#addShutdownHook-java.lang.Thread-
信號可以「殺」(人殺死可用的信號)來完成,你需要的進程ID做到這一點。 (ps ax | grep java)或類似的東西,或者當進程被創建時存儲進程ID(這在大多數linux啓動文件中使用,參見/etc/init.d)
便攜信令可以通過在您的Java應用程序中集成SocketServer。這並不困難,並讓您自由發送任何您想要的命令。
如果您的意思是最終條款而不是終結者;當System.exit()被調用時它們不會被擴展。 終結器應該可以工作,但不應該做任何更重要的事情,但應該打印調試聲明。他們很危險。
謝謝你的答案。關閉鉤子接縫就像在我的情況下工作。 但我也碰到了一個叫做Monitoring and Management beans的東西:
http://java.sun.com/j2se/1.5.0/docs/guide/management/overview.html
這給了一些很好的可能性,用於遠程監控和操作java進程。(在Java 5中經人介紹)
好吧,畢竟我已經選擇與「Java監視和管理」
Overview is here
這允許你從另外一個相對簡單的方式控制一個應用程序的工作準備。您可以從腳本中調用控制應用程序,以便在殺死它之前正常停止受控應用程序。
這裏是簡化的代碼:
受控應用:
與如下因素VM參數運行:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote .port = 9999
-Dcom.sun.management.jmxremote.authenticate =假
-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();
}
}
}
就是這樣運行它。 :-)
另一種方式:您的應用程序可以打開一個服務器socet並等待一個信息到達它。例如一個帶有「魔術」字符的字符串:)然後做出關閉:System.exit()的反應。您可以使用外部應用程序(如telnet)將這些信息發送到socke。
這是一個有點棘手,但便攜的解決方案:
我實現了Java代理。它可以在Github上:https://github.com/everit-org/javaagent-shutdown
有關解決方案的詳細說明,請訪問:https://everitorg.wordpress.com/2016/06/15/shutting-down-a-jvm-process/
你應該定義你的優雅是什麼意思。 (please) – 2008-10-10 13:23:03
我假設他們的意思是他們希望有機會在程序被終止之前清理資源,釋放,鎖定並刷新任何持久數據到磁盤。 – 2008-10-10 13:25:34