Как устранить проблему блокировки сессий в PHP из-за admin-ajax.php в WordPress

Как устранить проблему блокировки сессий в PHP из-за admin-ajax.php в WordPress WordPress

Если ваш хостинг начал выдавать предупреждения вроде «Обнаружена блокировка сессий в PHP» с упоминанием /wp-admin/admin-ajax.php, вы столкнулись с распространённой проблемой производительности WordPress. В вашем случае проблема проявляется при выполнении запросов через admin-ajax.php, что приводит к задержкам в 3–8 секунд. Это может приводить к замедлению работы сайта и увеличению нагрузки на сервер. В этой статье мы разберем причины проблемы и способы ее решения.

Что такое admin-ajax.php и почему возникают блокировки сессий?

Что такое admin-ajax php и почему возникают блокировки сессий

Файл admin-ajax.php используется WordPress для выполнения AJAX-запросов, например, в таких задачах как:

  • Обновление статистики плагинов.
  • Вызов функций администратора.
  • Управление заданиями в очереди.

Однако, многие плагины злоупотребляют этим механизмом, отправляя большое количество запросов. Если при этом PHP-сессии блокируются, каждый новый запрос ждет завершения предыдущего, что вызывает цепочку задержек.

Что такое блокировка сессий в PHP и почему она возникает?

В PHP сессии по умолчанию хранятся в файлах на сервере. Когда скрипт вызывает функцию session_start(), он открывает файл сессии и блокирует его (используя механизм LOCK_EX), чтобы другие запросы от того же пользователя не могли одновременно изменять данные. Блокировка снимается только после вызова session_write_close() или завершения работы скрипта. Если запрос, например, через admin-ajax.php, выполняется долго (например, из-за сложных вычислений или ожидания ответа от внешнего сервиса), все последующие запросы от того же пользователя «зависают», ожидая освобождения сессии.

В WordPress проблема часто связана с файлом admin-ajax.php, который используется для обработки асинхронных запросов (AJAX). Например:

  • Запрос as_async_request_queue_runner может быть частью плагина, работающего с очередями задач (например, All in One SEO или других инструментов оптимизации).
  • Общий запрос к admin-ajax.php часто вызывается ядром WordPress (функция Heartbeat API) или сторонними плагинами.

Если такие запросы занимают много времени, это приводит к блокировкам, особенно при высокой нагрузке или активной работе в админ-панели.

Шаги для устранения проблемы

1. Оптимизация Heartbeat API

Heartbeat API — это встроенный механизм WordPress, который отправляет регулярные запросы к admin-ajax.php для автосохранения, проверки активности и других задач в админ-панели. Он может быть причиной блокировок, если запросы выполняются слишком часто или долго.
Решение: Добавьте следующий код в файл functions.php вашей темы (желательно дочерней, чтобы обновления основной темы не затёрли изменения):

add_action('init', 'optimize_heartbeat_settings', 1);
    function optimize_heartbeat_settings() {
        // Отключаем Heartbeat везде, кроме редактора записей
        global $pagenow;
        if ($pagenow !== 'post.php' && $pagenow !== 'post-new.php') {
            wp_deregister_script('heartbeat');
        }
    }
    
    add_filter('heartbeat_settings', 'custom_heartbeat_frequency');
    function custom_heartbeat_frequency($settings) {
        // Увеличиваем интервал до 60 секунд (по умолчанию 15)
        $settings['interval'] = 60;
        return $settings;
    }

Данный код отключает Heartbeat API на всех страницах админ-панели, кроме редактора записей и страниц создания контента. А так же увеличивает интервал между запросами до 60 секунд, снижая нагрузку.

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

2. Проверка и оптимизация плагинов

Часто виновником данной проблемы являются плагины. Чтобы найти виновника:

Вариант 1. Попросите у хостера логи, если к ним нет доступа. У некоторых хостеров, например у Beget предупреждение высвечивается в панели и сводный отчет по нему можно отправить на email.

Отправка сводного отчета на email

в моем случае такой отчет выглядит так:

Пример отчета

Из этого отчета видно, что причиной проблемы скорее всего является плагин Custom Sidebars, который вызывает длительные AJAX-запросы через файл class-thelib.php в строке 145. Это связано с обработкой заданий в очереди (as_async_request_queue_runner), что вызывает значительные блокировки.

Вариант 2. Если логи для вас кажутся совсем непонятными или не можете их добиться от ТП. Тогда можете попробовать воспользоваться плагином Query Monitor (доступен в репозитории WordPress). Варианты действия примерно следующие:

  1. Зайдите в админ-панель WordPress и откройте раздел Query Monitor.
  2. Отфильтруйте запросы по admin-ajax.php и определите плагины, которые их генерируют.

Если виновник найден:

  • Обновите проблемные плагины.
  • Если обновление не помогает или их нет, замените данные плагины на альтернативы или настройте их, чтобы минимизировать количество запросов.

Если вы не можете отказаться от плагина, можете попробовать обратитесь к его разработчикам с описанием проблемы.

3. Закрытие сессий в коде

Если WordPress или плагин использует session_start() (что нестандартно для ядра, но возможно в кастомных решениях), нужно закрывать сессии вручную.
Для этого добавьте в functions.php следующий код для управления сессиями:

add_action('init', 'handle_php_sessions');
    function handle_php_sessions() {
        if (session_status() === PHP_SESSION_ACTIVE) {
            session_write_close(); // Закрываем сессию сразу после старта
        }
    }

Данный код проверяет, активна ли сессия, и закрывает её, чтобы избежать блокировок.

Данный вариант подходит, только в случае, если проблема вызвана кастомным кодом или старым плагином.
Если вы не уверены, используется ли session_start(), обратитесь к хостеру или разработчику для анализа логов.

4. Переход на Redis или Memcached

По умолчанию PHP хранит сессии в файлах, что вызывает блокировки при высокой нагрузке. Современные хостинги (например, Beget, SiteGround) поддерживают Redis или Memcached — системы кэширования, которые хранят сессии в памяти, устраняя файловые блокировки.

Для перехода:

  1. Проверьте у хостинга, доступен ли Redis/Memcached (обычно это указано в панели управления или техподдержке).
  2. Если доступен, включите его:
    • На Beget: в разделе «Настройки PHP» выберите Redis как обработчик сессий.
    • На других хостингах: отредактируйте php.ini, добавив session.save_handler = redis и session.save_path = "tcp://127.0.0.1:6379".
  3. Для WordPress установите плагин Redis Object Cache (автор: Till Krüss) и настройте его через wp-config.php:
    define('WP_REDIS_HOST', '127.0.0.1');
    define('WP_REDIS_PORT', 6379);
  4. Проверьте статус в админ-панели (раздел «Инструменты» → «Redis»).

Преимущества:

  • Ускоряет работу сайта.
  • Полностью устраняет файловые блокировки сессий.

Примечание. Требуется доступ к настройкам сервера. Если хостинг не поддерживает Redis, рассмотрите смену провайдера.

5. Отключение admin-ajax.php (радикальный метод)

Если блокировки связаны только с admin-ajax.php и вы готовы пожертвовать некоторыми функциями админ-панели, можно отключить его полностью.
Решение: Добавьте в functions.php:

add_action('admin_init', 'disable_admin_ajax');
    function disable_admin_ajax() {
        if (strpos($_SERVER['REQUEST_URI'], 'admin-ajax.php') !== false) {
            wp_die('admin-ajax.php отключён для оптимизации.');
        }
    }

Данный код блокирует все запросы к admin-ajax.php, устраняя источник проблемы.
Минусы данного решения:

  • Ломает функции, зависящие от AJAX (автосохранение, виджеты и т.д.).
  • Используйте только как временную меру или для фронтенда.

Рекомендации по выбору метода

  1. Начните с оптимизации Heartbeat API и проверки плагинов — это самые простые шаги, не требующие доступа к серверу.
  2. Если проблема сохраняется, попробуйте закрытие сессий или переход на Redis.
  3. Отключение admin-ajax.php — крайний вариант, если ничего не помогает.

Что еще может помочь

Если выше указанные методы не помоги, можно еще попробовать указанные ниже.

Замена PHP-сессий на альтернативы

Если ваш сайт использует PHP-сессии, перейдите на использование кукисов для хранения данных сессий. Это устраняет блокировки на уровне PHP.

В файле wp-config.php добавьте следующий код:

if (!defined('WP_SESSION_COOKIE')) {
        define('WP_SESSION_COOKIE', '_wp_session');
    }

Используйте библиотеку WP Session Manager, чтобы заменить стандартные PHP-сессии.

Использование REST API вместо admin-ajax.php

Современный WordPress предоставляет REST API, который более производителен и не вызывает блокировок PHP-сессий. Если вы разрабатываете свои плагины, замените вызовы admin-ajax.php на REST API.

Пример реализации:

add_action('rest_api_init', function () {
        register_rest_route('myplugin/v1', '/data', [
            'methods' => 'GET',
            'callback' => 'myplugin_get_data',
        ]);
    });
    
    function myplugin_get_data() {
        return rest_ensure_response(['message' => 'Hello, REST API!']);
    }

Кэширование

Для снижения нагрузки на сервер:

  • Установите и настройте плагин кэширования, например WP Rocket или W3 Total Cache.
  • Используйте серверное кэширование, если оно поддерживается вашим хостингом (например, OPcache или Redis).

Оптимизация cron-задач WordPress

WordPress использует wp-cron.php для выполнения запланированных задач. Если cron-задачи инициируются слишком часто, это может дополнительно нагружать admin-ajax.php.

Настройте выполнение cron-задач через сервер:

  1. Отключите встроенный WordPress cron: define('DISABLE_WP_CRON', true);
  2. Добавьте системное задание cron на сервере: */15 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron > /dev/null 2>&1

Проверка настроек сервера

Проверьте настройки сервера и убедитесь, что:

  • Используется последняя версия PHP.
  • Включено OPcache для кэширования скриптов.
  • Настройки MySQL оптимизированы под нагрузку.

Как проверить результат?

  • После каждого изменения очищайте кэш сайта (если используете плагины вроде WP Rocket или LiteSpeed Cache).
  • Мониторьте предупреждения от хостинга в течение 1–2 дней.
  • Используйте Query Monitor для анализа времени выполнения запросов.

Заключение

Проблема блокировки сессий в PHP из-за admin-ajax.php — это результат неправильного использования AJAX-запросов и неоптимальных настроек серверной части. Следуя описанным выше шагам, вы сможете существенно снизить нагрузку на сервер и улучшить производительность сайта.

Если у вас возникли сложности с выполнением шагов, обратитесь к специалистам или хостинг-провайдеру за дополнительной помощью.

Поделиться с друзьями
Алексей

Веб-дизайнер и SEO оптимизатор. Занимаюсь созданием сайтов с 2010 года и их продвижение с 2012 года!

Оцените автора
( Пока оценок нет )
Web-Revenue.ru
Добавить комментарий