Назад | Перейти на главную страницу

Ec2 Cronjobs - Высокая загрузка ЦП

У меня есть экземпляр EC2 (микро), на котором работает API cakephp. Этот экземпляр проходит проверку качества перед развертыванием в производственной среде.

В этом случае у нас есть 5 cronjobs, которые выполняются один раз в минуту. Эти cronjobs в 98% случаев запускают запросы Mysql и завершаются, так как делать нечего. Таким образом, в 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 / elasticbeanstalk / support / envvars && / var / app / current / bin / cake cronjob_number_one> / var / log / cronjobs_php 2> & 1 "]}]}}}

Каждый раз, когда правило cronjob активно, использование ЦП нашего экземпляра Ec2 увеличивается и продолжает расти до тех пор, пока экземпляр Ec2 не умрет. Вот график, чтобы увидеть, что происходит:

Увеличение ЦП за последнюю неделю до сегодняшнего дня.

Я установил SAR, чтобы проверять использование процессора в течение минуты, и вот что происходит:

Сар -у ВСЕ 1120

Как только я выключаю событие кукурузных заданий, процессор опускается до нормальных значений.

Я проверил папку журналов, и нет никаких ошибок или чего-то подобного.

Это случилось с кем-нибудь? Любая подсказка о том, как я могу решить эту проблему? Спасибо за вашу помощь!

PS: У нас есть другой продукт, в котором вместо cronjobs из командной строки у нас есть «cronjobs», которые отправляют HTTP-запрос к конечной точке. У нас более 30 «cronjobs» в производстве, и использование процессора далеко не так.

Моя догадка: Поскольку они запускаются одновременно, возможно, они создают некоторые состояние гонки или заблокировать базу данных, предотвратив успешное выполнение всех или некоторых из них. Я бы сказал, что, вероятно, только двое из них связаны и не могут закончить.

А поскольку каждую минуту запускается новое задание, претендентов на ресурс (предположительно 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). По сути, это так:

    1. вы начинаете работу cron
    2. это зовёт flock попытаться создать файл блокировки
    3. если это удастся -> запустить фактическую работу
    4. если нет (потому что старый все еще существует, потому что работа еще не завершена) -> выход

Надеюсь, это поможет :)