2012-02-09 95 views
0

我有一个jar,它在运行时浏览目录中的文件并在退出之前处理其中的10个文件。在shell脚本崩溃后可靠地重新启动java进程

我有一个shell脚本,它看起来是这样的:

while true; 
do java -jar myjar.jar 
sleep2; 
done 

我有一个运行在启动前一个像这样另一个shell脚本:

nohup loopscript.sh > /var/log/error.log 

的问题是,有时当它需要比系统更多的内存时,jar崩溃,整个循环似乎停止运行。当内存上限被击中时,我的日志文件以堆栈跟踪结束。

如何在碰撞后可靠地重新启动循环?我读elsewhere on SO像做

until myserver; do 
    echo "Server 'myserver' crashed with exit code $?. Respawning.." >&2 
    sleep 1 
done 

但如果MYSERVER本身就是一个循环,我故意停止罐10次运行后强制垃圾回收和减少中途死机的机会,这仅适用。我的逻辑是否有缺陷?我应该把jar放到一个循环中,并使用上面的方法在崩溃时重新启动它?

+0

你限制自己的10个文件,每次运行,由于内存?这听起来像是Java程序中的一个糟糕的内存泄漏。 – 2012-02-09 00:48:47

+0

该程序不会泄漏 - 我已经在成千上万的文件中测试过它。我只是有一种预感,即退出并每隔几秒重新启动一次,而不是保持它永久运行便宜。我误导了吗? – Ben 2012-02-09 01:06:35

回答

0

作为一个快速和解决方案,你可以杀死一些超时后的过程。这里有两个脚本父子关系:

  • b.sh - 父

    echo Parent running 
    while true; do 
        ./a.sh & 
        pid=$! 
        echo Child running as $pid 
        sleep 2 
        if [ "`ps -p $pid`" != "" ]; then 
        sh -c "/bin/kill $pid" >/dev/null 2>&1 
        echo Killed $pid 
        fi 
    done 
    
  • a.sh - 孩子

    echo Child running 
    seconds=$RANDOM 
    let "seconds %= 4" 
    sleep $seconds 
    echo Child finished 
    

然而,正如@ Jim Garrison指出,设计您的应用程序以正确运行可能要好得多,无论您的情况如何。通过这种方式,您实际上可以改进您的应用,并了解为什么需要这么多内存。您可能会解决一些将来会弹出的情况,但不可见,因为您只是通过重新启动来“解决”问题。

这就像玩俄罗斯轮盘赌 - 是的,你可能会得到幸运20倍成一排,但它会发生什么......

+0

该解决方案现在可以运行,但我开始发现,解决现有问题将是最佳的长期解决方案。感谢你的回答! – Ben 2012-02-09 02:43:11

+0

当然,本 - 是的,我最有可能回报调查的问题,而不是像这样绕过他们。取决于该项目,但如果它将被用于任何合理的时间,通常会浪费更多时间(和神经)修补,然后正确解决。 – 2012-02-10 03:45:14