У меня есть проект, который использует очереди Redis и Laravel (5.1).
В нашем случае после развертывания определенное задание стало давать сбой, что привело к отставанию в десятках тысяч заданий в redis. После обнаружения логической проблемы в моем коде в определенном классе заданий было развернуто исправление, в котором также была удалена переменная в классе.
Однако, поскольку класс сериализован и хранится в Redis, когда поставленные в очередь задания повторили попытку поставленного в очередь задания, затем произошел сбой, поскольку рабочий Laravel попытался получить доступ к уже не существующей переменной области действия класса. Я исправил эту проблему, выполнив дальнейшее развертывание с переменной обратно на месте.
Как этого можно избежать в будущем? Есть ли способ обновить сериализованный код задания или лучший способ отловить такого рода ошибки? Метод сериализованного объекта, используемый Laravel в Redis, создает зависимость между помещенным в очередь элементом и кодом Laravel, который я бы предпочел просто избежать.
Это была в значительной степени недокументированная проблема. В недавнем дополнении к документации говорится следующее, что может помочь решить проблему с помощью брошенного исключения и логического класса модели:
При внедрении модели Eloquent в задание она автоматически сериализуется перед помещением в очередь и восстанавливается при обработке задания. Однако, если модель была удалена во время ожидания задания для обработки работником, ваша работа может завершиться с ошибкой ModelNotFoundException.
Для удобства вы можете выбрать автоматическое удаление работ с отсутствующими моделями, установив для свойства deleteWhenMissingModels вашей работы значение true:
/**
* Delete the job if its models no longer exist.
*
* @var bool
*/
public $deleteWhenMissingModels = true;
Читайте об этом в контексте здесь:
Других решений пока нет …