最近迷上了定时任务crontab,发现crontab还是好用、省事。遇到两个小问题。
1、一个任务尚未执行完毕时,新任务又起来。比如,需要定时备份数据,但是第一次备份(数据量很大)尚未结束时,到了启动时刻,会再起一个备份任务。
多个相同的任务同时执行,可能会出现各种奇怪的情况。
这时,需要保证整个系统中,只有一份程序在运行。原理就是利用系统的资源,加一个标志,比如开始一个端口,比如对一个文件加锁等。我使用java实现的,可以这样做,任务起来时对一个文件加锁,结束时释放。新任务首先检查文件是否被加锁,如果已经加锁,则不执行。一个简单的实现demo:
String fileName = ""; // 待加锁文件路径
FileOutputStream fos = new FileOutputStream(fileName);
FileChannel fc = fos.getChannel(); //获取FileChannel对象
FileLock fileLock = fc.tryLock(); // 尝试加锁
if(null != fileLock) {
System.out.println("加锁成功");
}else {
System.out.println("加锁失败,已经有一份程序在运行,本程序退出");
System.exit(0);
}
// 在这里实现自己的功能
fileLock.release(); //释放文件锁
fos.close(); //关闭文件写操作
2、使用crontab启动任务时,使用ps查看进程状态,发现同时出现两个进程。一个进程是我要执行的程序,也就是我的任务启动命令,另外一个进程是:
/bin/sh -c XXX # XXX是我的任务启动命令
查了一下,这似乎是crontab的实现机制造成的。在crontab中配置的命令,被/bin/sh -c的形式执行。当然,我的任务还是只运行了一份,没有问题。
这可能是linux上出现的现象,在centOS上,试了一下,没有这个问题,也就是查看进程,只有一个任务,没有“/bin/sh -c ”这行。