Есть MySQL база, в которой есть таблица queue. В эту таблицу поступают задания для выполнения.
Задания должны распределяться между серверами и процессами. Одна и та же задача не должна попасть к разным процессам. Например:
Сервер-1: Сервер-2: Сервер-3:
процесс-а процесс-в процесс-а
процесс-б процесс-б процесс-д
процесс-б
Ниже приведен псевдо-код, как я вижу решение этой задачи? Какие минусы? Может есть более элегантное решение?
CREATE TABLE `queue` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`script` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`args` mediumtext COLLATE utf8_unicode_ci,
`status` enum('waiting','process','finished') COLLATE utf8_unicode_ci DEFAULT 'waiting',
`run_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`process_id` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
<?php
set_time_limit(0);
// Получаем уникальный ID процесса: 192.168.0.10.xxxx
function getProcessId() {
return gethostbyname(gethostname()).".".getmypid();
}
if(!$db->execute("UPDATE `queue` SET status=:status_process, process_id=:process_id WHERE status=:status_waiting AND run_at <= :time", [
":status_process"=>"process",
":process_id"=>getProcessId(),
":status_waiting"=>"waiting",
":time"=>date("Y-m-d H:i:s"),
])) {
return null;
}
$processes = $db->queryAll("SELECT * FROM queue WHERE process_id=:process_id AND status=:status", [
":status"=>"waiting",
":process_id"=>getProcessId(),
]);
foreach($processes as $process) {
// Необходимые манипуляции
$db->execute("UPDATE `queue` SET status=:status_finished WHERE id=:id", [
":status_finished"=>"finished",
":id"=>$process['id'],
]);
}
_____________
Заработок для веб-разработчиков: CodeCanyon
Мое Портфолио