Ec2 Cronjobs - высокая загрузка процессора
У меня есть экземпляр EC2 (микро), использующий API CakePHP. Этот экземпляр служит для проверки качества перед развертыванием в производство.
В этом случае у нас есть 5 cronjobs, которые запускаются раз в минуту. Эти cronjobs в 98% случаев запускают Mysql Query и завершают работу, так как ничего не нужно делать. Итак, в основном, в 98% случаев каждую минуту выполняется 5 запросов mysql.
Эти cronjobs настраиваются с помощью CloduWatch Events > Rules, которые содержат 5 cronjobs, установленных как Documents. Вот пример одного из наших документов:
{"schemaVersion": "1.2", "description": "CronjobNumberOne", "parameters": {
}, "runtimeConfig": {"aws: runShellScript": {"properties": [{"id": "0.aws:runShellScript", "runCommand": [". / opt /asticbeanstalk/support/envvars && /var/app/current/bin/cake cronjob_number_one > /var/log/cronjobs_php 2>&1"] } ] } } }
Каждый раз, когда правило cronjob активно, использование нашего экземпляра Ec2 увеличивается и продолжает расти, пока экземпляр Ec2 не умрет. Вот график, чтобы увидеть, что происходит:
Увеличение загрузки процессора за последнюю неделю, до сегодняшнего дня.
Я установил SAR для проверки использования процессора за минуту, и вот что происходит:
Как только я выключаю событие кукурузных початок, процессор понижается до нормальных значений.
Я проверил папку журналов, и нет ошибки или что-то в этом роде.
Это случилось с кем-нибудь? Любая подсказка, как я могу решить эту проблему? Спасибо за вашу помощь!
PS: у нас есть другой продукт, у которого вместо cronjobs в командной строке есть "cronjobs", которые отправляют HTTP-запрос к точке. У нас более 30 "cronjobs" на производстве, и использование ЦП близко к этому.
1 ответ
Мое предположение: поскольку они запускаются одновременно, возможно, они создают некоторое состояние гонки или блокируют базу данных, препятствуя успешному завершению всех или некоторых из них. Я бы сказал, что, вероятно, только двое из них связаны и не могут закончить.
И поскольку новая работа запускается каждую минуту, появляется все больше и больше претендентов на ресурс (предположительно MySQL), ни один из них не может выполнить свою работу из-за некоторых блокировок. Использование ресурсов в экземпляре продолжает расти, и экземпляр в конечном итоге умирает.
Это мое предположение.
Что делать: когда это происходит с экземпляром SSH и делать ps -faxu
и / или использовать top
чтобы выяснить, какие задания cron все еще выполняются. Вы сможете узнать из названия процесса.
Следующий шаг - убедиться, что задание cron-нарушителя выполняется только один раз за раз.
У вас есть несколько вариантов:
Простым и, вероятно, не очень надежным является распространение заданий cron в течение минуты. Что-то вроде готовящегося
sleep 10
/sleep 20
/...:sleep 10; . /opt/elasticbeanstalk/support/envvars && /var/app/current/bin/cake cronjob_number_one > /var/log/cronjobs_php 2>&1
Лучше, но немного сложнее было бы использовать семафоры, например, с помощью
flock(1)
, По сути, это то, как это работает:- вы начинаете работу cron
- это вызывает
flock
попытаться создать файл блокировки - если это удастся -> запустить фактическую работу
- если нет (потому что старый еще существует, потому что задание еще не закончено) -> выход
Надеюсь, это поможет:)