2012-02-09 58 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