Вопрос или проблема
У меня есть несколько скриптов, требующих больших ресурсов ЦП, которые я не хочу запускать одновременно. Время от времени скрипты пересекаются и вызывают сбой сервера. Уже при 2 ГБ контейнер MySQL все еще аварийно завершает работу.
У меня настроен cron, который запускает example.com/cron.php?do_cron=randstr каждые 15 минут.
Есть ли способ установить блокировку и запускать только одну задачу cron за раз? Когда она завершится, следующая задача должна запуститься.
Я знаю, что этого можно достичь с помощью механизма блокировок файлов PHP (но в этом случае следующая задача не ставится в очередь). Не уверен, делает ли WP это самостоятельно.
Любая помощь будет оценена!
Простой Cronjob Walker
- Создайте CPT
cronjob
для ваших cronjob’ов. - Добавьте соответствующие метаданные поста (действие, last_executed и все, что вам нужно)
-
Создайте функцию walker
function my_cronjob_walker() { $args= array( 'post_type' => 'cronjob', 'posts_per_page' => 1, 'meta_key' => 'last_executed', 'orderby' => 'meta_value', ); $cronjob = new WP_Query($args); if ($cronjob->have_posts()) while ($cronjob->have_posts()) { $cronjob->the_post(); // выполняйте ваши задачи cron здесь do_action(get_post_meta(get_the_ID(), 'action', true)); update_post_meta(get_the_ID(), 'last_executed', date('c')); } } if ( ! wp_next_scheduled( 'do_cronjob_walker' ) ) { wp_schedule_event( time(), 'hourly', 'do_cronjob_walker' ); } add_action( 'do_cronjob_walker', 'my_cronjob_walker' );
Ответ или решение
Оптимизация Cron-задач в WordPress: Блокировка и Очередь
Ваша задача по выполнению интенсивных скриптов в WordPress без одновременного их выполнения может быть решена несколькими способами. Ниже представлено подробное описание, как гарантировать, что эти задачи будут выполняться последовательно, а не одновременно, что приведет к сбоям и перегрузкам сервера.
Проблема, с которой вы столкнулись
Как указано в вашем вопросе, вы используете crontab для запуска скрипта cron.php
каждые 15 минут. Однако из-за интенсивности ваших скриптов возможно их перекрытие, что приводит к перегрузке системы и сбоям, особенно в вашем случае, где используется контейнер MySQL с ограниченным объемом памяти.
Решение с использованием блокировки
WordPress предоставляет механизмы обработки задач с использованием WP-Cron, но при этом не всегда гарантируется последовательность выполнения. Для решения вашей проблемы можно использовать механизмы блокировки и очереди.
-
Создание пользовательского типа записи (CPT) для Cron-задач:
Создайте CPT с названиемcronjob
, который будет хранить ваши задачи cron вместе с метаданными, такими как последнее время выполнения и действие, которое необходимо выполнить.function create_cronjob_cpt() { register_post_type('cronjob', array( 'labels' => array('name' => __('Cronjobs')), 'public' => false, 'has_archive' => false, 'supports' => array('title'), )); } add_action('init', 'create_cronjob_cpt');
-
Добавление и обновление метаданных:
При добавлении записи в типcronjob
, укажите необходимое действие и время последнего выполнения.function add_cronjob($action) { $post_id = wp_insert_post(array( 'post_type' => 'cronjob', 'post_title' => 'Cronjob for ' . $action, 'post_status' => 'publish', )); update_post_meta($post_id, 'action', $action); update_post_meta($post_id, 'last_executed', null); }
-
Создание функции для обработки задач (Walker):
Используйте функцию, которая будет вызывать только одну задачу крона за раз, блокируя выполнение следующих задач до завершения текущей.function my_cronjob_walker() { $args= array( 'post_type' => 'cronjob', 'posts_per_page' => 1, 'meta_key' => 'last_executed', 'orderby' => 'meta_value', 'order' => 'ASC', ); $cronjob = new WP_Query($args); if ($cronjob->have_posts()) { while ($cronjob->have_posts()) { $cronjob->the_post(); // Выполнение вашей cron задачи do_action(get_post_meta(get_the_ID(), 'action', true)); update_post_meta(get_the_ID(), 'last_executed', date('c')); } wp_reset_postdata(); // Обязательно сбрасываем данные после цикла } } if ( ! wp_next_scheduled( 'do_cronjob_walker' ) ) { wp_schedule_event(time(), 'hourly', 'do_cronjob_walker'); } add_action('do_cronjob_walker', 'my_cronjob_walker');
Заключение
Приведенные выше шаги обеспечивают последовательное выполнение ваших cron-задач в WordPress и предотвращают их одновременное выполнение, что сэкономит ресурсы вашего сервера и минимизирует риск его перегрузки. Этот подход позволит вам эффективно и надежно управлять вашими скриптами.
Для улучшения производительности не забывайте регулярно проверять и оптимизировать ваши SQL-запросы и использовать кэширование, чтобы минимизировать нагрузку на базу данных. Также стоит рассмотреть возможность запуска таких задач в более позднее время, когда нагрузка на сервер минимальна.
SEO-Оптимизация
Для повышения видимости данной информации при поисковых запросах, используйте ключевые слова и фразы, такие как "WordPress cron задачи", "последовательное выполнение cron задач в WordPress" и "блокировка cron задач WordPress".
Следуя этим шагам, вы сможете не только устранить проблему, но и обеспечить ровную работу вашего веб-приложения на платформе WordPress.