虽然有一个公认的答案,但有一些简单的本土解决方案没有上面列出的错误。 wget解决方案可以很好地确保单个服务器运行代码,但会增加安全性问题(您应该使用共享的专用访问密钥来保护URL),并且@sourcedelica还指出了哪个服务器应该实际调用的问题cron任务。
我倾向于去哪些工作,无论你的系统数量的解决方案 - 而且也不需要为不同的系统不同的cron配置。
的假设是,在路上你可能会增加新的机器,你的主服务器(一个配置来运行你的cron任务,例如)可能死亡或终止。
我已经开发了一个解决方案使用其可以用两个简单的表来实现集群数据库锁:
CREATE TABLE `Server` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uname` varchar(32) NOT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`alive` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `Lock` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
`code` varchar(128) NOT NULL,
`pid` int(10) unsigned DEFAULT NULL,
`server` int(10) unsigned DEFAULT NULL,
`locked` timestamp NULL DEFAULT NULL,
`used` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `code` (`code`)
);
每个系统具有独特的uname
,如果不存在登记的记录;每次更新alive
。
获得锁:一旦你用的32。如果server
和pid
都是NULL id
有你Lock
SELECT * FROM Lock WHERE code='cron-cluster';
如果它不存在,
INSERT INTO `Lock` ...
,设置它们到我的服务器id
和当前进程ID,使用数据库的原子性质来确保只有一个。
UPDATE Lock SET server=1,pid=4233 WHERE id=32 AND server IS NULL and pid IS NULL;
然后,你再一个选择,看看你是否真正获得它(假设n个不同的机器正试图获得在同一时间锁):
SELECT COUNT(id) FROM Lock WHERE code='cron-cluster' AND server=1 AND pid=4233;
如果结果是1 ,你已经获得锁定,0意味着另一个过程。
最后需要的是让每个服务器清理死锁和死亡服务器;每个服务器负责检查每个锁定的Lock
正在运行的活动进程,并且在某个超时之后,Server
未更新为alive
时,删除与该服务器及其Server
记录关联的所有锁定。
我添加其他的服务器性能的Server
表允许的磁盘空间,CPU等的监测
虽然没有强大的石英集群,它可以解决你的问题。
此外,刚刚发现rcron也可以解决它:https://code.google.com/p/rcron/ – razzed