User1599237 से उत्तर के सिद्धांतों के आधार पर , जहां आप क्रोन नौकरियों को सभी उदाहरणों पर चलने देते हैं, लेकिन फिर नौकरियों की शुरुआत में निर्धारित करते हैं कि क्या उन्हें चलाने की अनुमति दी जानी चाहिए, मैंने एक और समाधान किया है।
बजाय चल रहे उदाहरणों को देखने के (और अपनी एडब्ल्यूएस कुंजी और गुप्त स्टोर करने के लिए) मैं MySQL डेटाबेस का उपयोग कर रहा हूं जिसे मैं पहले से ही सभी उदाहरणों से जोड़ रहा हूं।
इसका कोई डाउनसाइड नहीं है, केवल सकारात्मक:
- कोई अतिरिक्त उदाहरण या खर्च नहीं
- रॉक सॉलिड सॉल्यूशन - दोहरे निष्पादन का कोई मौका नहीं
- स्केलेबल - स्वचालित रूप से आपके उदाहरणों को ऊपर और नीचे स्केल किया जाता है
- असफलता - स्वचालित रूप से काम करने की स्थिति में एक विफलता होती है
वैकल्पिक रूप से, आप डेटाबेस के बजाय आम तौर पर साझा किए गए फाइल सिस्टम (जैसे एडब्ल्यूएस ईएफएस एनएफएस प्रोटोकॉल के माध्यम से) का उपयोग कर सकते हैं।
निम्न समाधान PHP फ्रेमवर्क Yii के भीतर बनाया गया है, लेकिन आप इसे आसानी से किसी अन्य ढांचे और भाषा के लिए अनुकूलित कर सकते हैं। इसके अलावा अपवाद हैंडलर Yii::$app->system
मेरे खुद का एक मॉड्यूल है। इसे आप जो भी उपयोग कर रहे हैं, उसके साथ बदलें।
public function actionLock() {
$argsAll = $args = func_get_args();
if (!is_numeric($args[0])) {
\Yii::$app->system->error('Duration for obtaining process lock is not numeric.', ['Args' => $argsAll]);
}
if (!$args[1]) {
\Yii::$app->system->error('Job name for obtaining process lock is missing.', ['Args' => $argsAll]);
}
$durationMins = $args[0];
$jobName = $args[1];
$instanceID = null;
unset($args[0], $args[1]);
$command = trim(implode(' ', $args));
if (!$command) {
\Yii::$app->system->error('Command to execute after obtaining process lock is missing.', ['Args' => $argsAll]);
}
if (file_exists('/etc/elasticbeanstalk/.aws-eb-system-initialized')) {
if ($awsEb = file_get_contents('/etc/elasticbeanstalk/.aws-eb-system-initialized')) {
$awsEb = json_decode($awsEb);
if (is_object($awsEb) && $awsEb->instance_id) {
$instanceID = $awsEb->instance_id;
}
}
}
$updateColumns = false;
$affectedRows = \Yii::$app->db->createCommand()->upsert('system_job_locks', [
'job_name' => $jobName,
'locked' => gmdate('Y-m-d H:i:s'),
'duration' => $durationMins,
'source' => $instanceID,
], $updateColumns)->execute();
if ($affectedRows == 0) {
$affectedRows = \Yii::$app->db->createCommand()->update('system_job_locks', [
'locked' => gmdate('Y-m-d H:i:s'),
'duration' => $durationMins,
'source' => $instanceID,
],
'job_name = :jobName AND DATE_ADD(locked, INTERVAL duration MINUTE) < NOW()', ['jobName' => $jobName]
)->execute();
if ($affectedRows == 0) {
exit;
}
}
$command = str_replace('StdOUT', '>', $command);
$command = str_replace('StdERR.ditto', '2>&1', $command);
$command = str_replace('StdERR', '2>', $command);
$command .= ' &';
$output = []; $exitcode = null;
exec($command, $output, $exitcode);
exit($exitcode);
}
यह डेटाबेस स्कीमा है जिसका मैं उपयोग कर रहा हूं:
CREATE TABLE `system_job_locks` (
`job_name` VARCHAR(50) NOT NULL,
`locked` DATETIME NOT NULL COMMENT 'UTC',
`duration` SMALLINT(5) UNSIGNED NOT NULL COMMENT 'Minutes',
`source` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`job_name`)
)