雖然有一個公認的答案,但有一些簡單的本土解決方案沒有上面列出的錯誤。 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