Графики Laravel в распределенном приложении

Мое приложение работает на 3 серверах за балансировщиком нагрузки. Поэтому он не имеет состояния, все данные хранятся в Redis и MySQL.

Если на моих машинах работает планировщик Cron Artisan, я предполагаю, что одна и та же задача будет выполнена 3 раза. Однажды на каждой машине, так как нет сведений о том, что было запущено, совместно используется ими как таблица базы данных.

Каковы решения?

4

Решение

редактировать: В последних версиях Laravel, теперь встроенный.

$schedule->command('foo:bar')->onOneServer();

Мы делаем это в командах Artisan, которые должны запускаться только на одном сервере за выполнение cron:

public function handle()
if(!Cache::add(get_class($this), true, 0.5)) {
return false;
}

Cache::add является синхронным и вернет значение false, если ключ уже существует, поэтому даже если все три сервера будут выполняться в одну и ту же микросекунду, только один сервер продолжит выполнение остальной части задачи.

Другим распространенным вариантом является включение cron только на одном сервере в кластере или наличие выделенного сервера для самого cron.

5

Другие решения

Если ваш сервер Redis является общим для всех серверов, вы можете создать некоторую логику, например выбрать сервер-лидер.

Ваша логика приложения должна проверить лидера перед обработкой. Образец фрагмента:

if(redis.get("LEADER").equals(currentappserver))
process();
else if(redis.get("LEADER")==null && selectLeader()) -> a lua script call.
process();

Поскольку redis является однопоточным, напишите логику, подобную этой, в скрипте lua:

selectLeader()
if redis.get("LEADER")==null
redis.set("LEADER",current_node)
return true;
else
return false;

Он будет атомарным, и всегда будет доступен только один поток лидеров.

P.s: Коды, которые я предоставил, являются псевдокодом vauge, не точным кодом.

2

Laravel 5.4 поддерживает настройки нескольких серверов с использованием планировщика если обновление является вариантом.

Он использует метод, аналогичный принятому ответу от ceejayoz.

Вместо того, чтобы использовать файловую систему для хранения файла блокировки, мы используем хранилище кэша, чтобы позволить любому серверу блокировать / проверять запланированные события.

https://github.com/laravel/internals/issues/69

0
По вопросам рекламы [email protected]