TL; DR:
См. Рабочую .ebextentions
конфигурацию в конце ответа.
Окружающая среда
Как запустить код Laravel с помощью crontab?
Ответы на этот вопрос, конечно, самые очевидные, и, если вы хоть немного в Laravel, вы наверняка знаете ответ: Планирование !
Я не буду утомлять вас объяснением замечательной вещи, которая является Laravel Scheduling, так как вы можете прочитать об этом в документации самостоятельно.
Но главное, что нам нужно взять с собой, - это то, что Laravel Scheduling использует для выполнения crontab, как описано в документации:
* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
Что подводит нас к следующему, и более сложному вопросу ...
Как настроить crontab в моей среде Elastic Beanstalk?
На первый взгляд ответ на этот вопрос может показаться довольно простым. Я нашел это в Центре знаний AWS: Как создать задание cron для экземпляров EC2 в среде Elastic Beanstalk?
Здесь они описывают, как настроить работу cron на вашем компьютере Elastic Beanstalk EC2, используя .ebextentions. Вкратце, он создает новый файл в каталоге /etc/cron.d/
, в который мы помещаем желаемое задание cron.
Файлы в этом каталоге затем обрабатываются crontab как пользователь root
. Есть несколько ловушек, в которые я ходил, как я прокомментировал ниже:
files:
# The name of the file should not contain any dot (.) or dash (-), this can
# cause the script not to run. Underscore (_) is OK.
"/etc/cron.d/mycron":
# This permissions is important so that root user can run the script.
mode: "000644"
# As the file is run by the root user it needs to be the owner of the file.
owner: root
# For consistency it's a good idea to have root as the group aswell.
group: root
# NOTE: We need to explicitly tell the cron job to be run as the root user!
content: |
* * * * * root /usr/local/bin/myscript.sh
# There need to be a new line after the actual cron job in the file.
Как только мы избавимся от всех этих ловушек, пришло время поставить нашу задачу cron для Laravel Scheduling сверху. Это должно выглядеть примерно так:
files:
"/etc/cron.d/schedule_run":
mode: "000644"
owner: root
group: root
content: |
* * * * * root php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
Это не будет работать в большинстве случаев, хотя . Это связано с тем, что Laravel Scheduler не будет иметь доступа к вашим переменным ENV и должен явно не соответствовать настройкам вашей базы данных.
Я нашел ответ на этот вопрос здесь: Как получить расписание задач Laravel, работающее с AWS Elastic Beanstalk Cron
Итак, большой крик Джорджу Беннишу; Я приветствую вас, сэр, за то, что поделился этим!
Итак, с помощью этой последней части головоломки я наконец-то смог заставить установку работать правильно:
Рабочий раствор
Структура файла:
[Project root]
|-- .ebextensions
| |-- cronjob.config
cronjob.config:
files:
"/etc/cron.d/schedule_run":
mode: "000644"
owner: root
group: root
content: |
* * * * * root . /opt/elasticbeanstalk/support/envvars && /usr/bin/php /var/www/html/artisan schedule:run 1>> /dev/null 2>&1
commands:
remove_old_cron:
command: "rm -f /etc/cron.d/*.bak"
Совет при использовании планирования Laravel на AWS Elastic Beanstalk!
Поскольку одной из ключевых функций Elastic Beanstalk является то, что он может автоматически масштабировать и добавлять больше серверов, когда это необходимо, вам может потребоваться взглянуть на новую функцию в планировании Laravel: Выполнение задач на одном сервере .
Во многих случаях вы не хотите, чтобы ваша задача cron выполнялась более чем на одном сервере. Например, если у вас есть запланированная команда для отправки электронных писем, вы не хотите, чтобы они отправлялись несколько раз.
ПРИМЕЧАНИЕ: Для этого необходимо использовать memcached или redis в качестве механизма кэширования, как указано в документации. Если нет, взгляните на сервис AWS Elasticache .
ПРИМЕЧАНИЕ 2: При использовании onOneServer()
вы должны присвоить запланированной задаче имя с помощью метода name()
(перед вызовом onOneServer()
). Вот так:
$schedule->command('my:task')
->name('my:task')
->daily()
->onOneServer();