Как остановить процесс java изящно?



Как я могу остановить процесс Java изящно в Linux и Windows?



когда Runtime.getRuntime().addShutdownHook получить вызов, и когда это не так?



Как насчет финализаторов, они помогают здесь?



могу ли я отправить какой-то сигнал в процесс Java из оболочки?



Я ищу предпочтительно портативные решения.

800   7  

7 ответов:

крючки выключения выполняются во всех случаях, когда виртуальная машина не была принудительно убита. Итак, если вы должны были выдать" стандартное " убийство (SIGTERM из команды kill), то они будут выполняться. Точно так же они будут выполняться после вызова System.exit(int).

однако трудно убить (kill -9 или kill -SIGKILL) тогда они не будут выполнять. Точно так же (и очевидно) они не будут выполняться, если вы вытащите питание из компьютера, бросите его в чан с кипящей лавой или разобьете процессор на куски кувалдой. Вы хотя, наверное, уже знал об этом.

финализаторы действительно должны работать, но лучше не полагаться на это для очистки выключения, а скорее полагаться на ваши крючки выключения, чтобы остановить все чисто. И, как всегда, будьте осторожны с тупиками (я видел слишком много крючков выключения, которые висят весь процесс)!

ОК, после всех возможностей, которые я выбрал для работы с "Java Monitoring and Management"
описание здесь
Это позволяет вам управлять одним приложением из другого относительно простым способом. Вы можете вызвать управляющее приложение из сценария, чтобы остановить управляемое приложение изящно, прежде чем убить его.

вот упрощенный код:

контролируемые приложения:
запустите его с помощью следующей виртуальной машины параметры:
-протокол DCOM.солнце.управление.jmxremote
-протокол DCOM.солнце.управление.jmxremote.порт=9999
-протокол DCOM.солнце.управление.jmxremote.проверка подлинности=ложь
-протокол DCOM.солнце.управление.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");
    }
}
}

управление приложения:
запустите его с помощью остановка или 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 и ждать поступившей к нему информации. Например, строка с "волшебным" словом :), а затем реагировать, чтобы сделать shutdown: System.выход.)( Вы можете отправить такую информацию socke с помощью внешнего приложения, такие как telnet.

Аналогичный Вопрос здесь

финализаторы в Java плохие. Они добавляют много накладных расходов на сбор мусора. Избегайте их, когда это возможно.

shutdownHook будет вызываться только при завершении работы виртуальной машины. Я думаю, что это очень хорошо может сделать то, что вы хотите.

вот немного хитрое, но портативное решение:

  • в вашем приложении реализовать крюк выключения
  • Если вы хотите завершить работу JVM изящно, установите Java Agent что называет

сигнализация в Linux может быть выполнена с помощью "kill" (man kill для доступных сигналов), для этого вам понадобится идентификатор процесса. (ps ax / grep java) или что-то в этом роде, или сохранить идентификатор процесса при создании процесса (это используется в большинстве файлов запуска linux, см. /etc/init.г)

портативная сигнализация может быть выполнена путем интеграции SocketServer в вашем приложении java. Это не так сложно и дает вам свободу отправлять любую команду, которую вы хотите.

Если вы означало, наконец, предложения вместо финализаторов; они не расширяются, когда система.вызывается exit (). Финализаторы должны работать, но на самом деле не должны делать ничего более значительного, кроме печати инструкции отладки. Они опасны.

Спасибо за ответы. Выключение крючки швы, как что-то, что будет работать в моем случае. Но я также столкнулся с тем, что называется мониторингом и Управлением beans:
http://java.sun.com/j2se/1.5.0/docs/guide/management/overview.html
Это дает некоторые хорошие возможности для удаленного мониторинга и манипулирования процессом java. (Был представлен в Java 5)

Comments

    Ничего не найдено.