在做完一个项目程序后,有时会有两种需求想法。
1.在每次机器重启后自动运行程序。
2.在程序运行过程中如果发生了死锁、内存溢出或程序崩溃等问题时程序能自动重启。
当然。要实现这两种效果的方案有很多。可以在系统引导文件中加入开机运行程序引导,也可以写一个系统监听程序等等。
现在有一个更简单的解决方案。有一个java程序叫Java Service Wrapper。这是用来在windows或unix/linux系统中将java程序包装成系统服务并执行守护进程。
Java Service Wrapper有三个版本。professional/standard/community 前两个版本要收费功能也更多。对我们来说,社区版的已经够用了,(对于死锁重启需要收费版的)。
从软件的名子上就能看出来。这个软件是用来包装的。我们的程序完成以后会有一个main入口。wrapper就是将这个main方法进行包装再提供自己的一个main入口。这样,我们在运行时都是运行的wrapper的程序。它会建立各种监控和服务,在建立完成后再加载运行被包装的方法。等监控到运行的程序出问题了就会进行相应的处理。
1.从官网http://wrapper.tanukisoftware.com上下载wrapper的软件。
2.我们只需要几个核心的文件
针对不同程序有不同的实现方式。
1.如果你的程序是不间断运行的。则只需要设置配置文件即可。
2.如果你的程序只是在系统启动时运行一次,或不需要连续运行的,则要加入入口包装类。不然,虽然你的程序已经执行成功且退出了(如:在系统启动时检查下环境再给你的提示信息就结束)。但wrapper会认为你的程序不应该结束,会不停的重启你的服务。这时你要加入包装类就没有这个问题了。
原程序内容
public class Out{ public static void main(String[] args) throws Exception{ System.out.println("\u7a0b\u5e8f\u5f00\u59cb\u8fd0\u884c..."); } }
原程序中只是打印一句话就结束。而我们要的效果是不间断运行,所以wrapper会不断的重启原程序,而会不断的打印语句。
只要改配置文件中的 wrapper.java.mainclass=Out 即可
在运行App.bat之后,你会发现程序会不断的被重启。
原程序内容
public class Out{ public static void main(String[] args) throws Exception{ System.out.println("\u7a0b\u5e8f\u5f00\u59cb\u8fd0\u884c..."); String a="a"; try{ Thread.sleep(2000); }catch(Exception e){} System.out.println("\u7a0b\u5e8f\u5f00\u59cb\u5185\u5b58\u6ea2\u51fa..."); for(int i=0;i<999999999;i++){ a+=a; } System.out.println("end"); } }
原程序中应该能打印3句话,但在打印第二句后就会内存被溢出,最后的end不会被打印。但wrapper发现内存溢出后,会自动重启程序,再次不停的打印前两句和重启。
更改配置文件中内容
wrapper.java.mainclass=Out
wrapper.filter.trigger.1000=Exception in thread "*" java.lang.OutOfMemoryError
wrapper.filter.action.1000=RESTART
public class Out{ public static void main(String[] args) throws Exception{ System.out.println("\u7a0b\u5e8f\u5f00\u59cb\u8fd0\u884c..."); String a="a"; try{ Thread.sleep(2000); }catch(Exception e){} if(args.length>0){ System.out.println("\u7a0b\u5e8f\u5f00\u59cb\u5185\u5b58\u6ea2\u51fa..."); for(int i=0;i<999999999;i++){ a+=a; } } System.out.println("end"); } }
import org.tanukisoftware.wrapper.WrapperListener; import org.tanukisoftware.wrapper.WrapperManager; public class Main implements WrapperListener{ public static void main(String[] args) throws Exception{ Out.main(args); WrapperManager.start(new Main(),args); } public Integer start(String[] args) { System.out.println("start()"); return null; } public int stop(int exitCode) { System.out.println("stop(" + exitCode + ")"); return exitCode; } public void controlEvent(int event) { System.out.println("controlEvent(" + event + ")"); } }
wrapper.filter.trigger.1000=Exception in thread "*" java.lang.OutOfMemoryError
wrapper.filter.action.1000=RESTART
好了,Java Service Wrapper的基本使用就是这么简单。
把第四个示例的内存溢出打个包在这里备份下。以便自己以后使用。