- Что такое admin-ajax.php и почему возникают блокировки сессий?
- Что такое блокировка сессий в PHP и почему она возникает?
- Шаги для устранения проблемы
- 1. Оптимизация Heartbeat API
- 2. Проверка и оптимизация плагинов
- 3. Закрытие сессий в коде
- 4. Переход на Redis или Memcached
- 5. Отключение admin-ajax.php (радикальный метод)
- Рекомендации по выбору метода
- Что еще может помочь
- Замена PHP-сессий на альтернативы
- Использование REST API вместо admin-ajax.php
- Кэширование
- Оптимизация cron-задач WordPress
- Проверка настроек сервера
- Как проверить результат?
- Заключение
Если ваш хостинг начал выдавать предупреждения вроде «Обнаружена блокировка сессий в PHP» с упоминанием /wp-admin/admin-ajax.php
, вы столкнулись с распространённой проблемой производительности WordPress. В вашем случае проблема проявляется при выполнении запросов через admin-ajax.php
, что приводит к задержкам в 3–8 секунд. Это может приводить к замедлению работы сайта и увеличению нагрузки на сервер. В этой статье мы разберем причины проблемы и способы ее решения.
Что такое 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.
в моем случае такой отчет выглядит так:
Из этого отчета видно, что причиной проблемы скорее всего является плагин Custom Sidebars, который вызывает длительные AJAX-запросы через файл class-thelib.php
в строке 145. Это связано с обработкой заданий в очереди (as_async_request_queue_runner
), что вызывает значительные блокировки.
Вариант 2. Если логи для вас кажутся совсем непонятными или не можете их добиться от ТП. Тогда можете попробовать воспользоваться плагином Query Monitor (доступен в репозитории WordPress). Варианты действия примерно следующие:
- Зайдите в админ-панель WordPress и откройте раздел Query Monitor.
- Отфильтруйте запросы по 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 — системы кэширования, которые хранят сессии в памяти, устраняя файловые блокировки.
Для перехода:
- Проверьте у хостинга, доступен ли Redis/Memcached (обычно это указано в панели управления или техподдержке).
- Если доступен, включите его:
- На Beget: в разделе «Настройки PHP» выберите Redis как обработчик сессий.
- На других хостингах: отредактируйте
php.ini
, добавивsession.save_handler = redis
иsession.save_path = "tcp://127.0.0.1:6379"
.
- Для WordPress установите плагин Redis Object Cache (автор: Till Krüss) и настройте его через
wp-config.php
:define('WP_REDIS_HOST', '127.0.0.1'); define('WP_REDIS_PORT', 6379);
- Проверьте статус в админ-панели (раздел «Инструменты» → «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 (автосохранение, виджеты и т.д.).
- Используйте только как временную меру или для фронтенда.
Рекомендации по выбору метода
- Начните с оптимизации Heartbeat API и проверки плагинов — это самые простые шаги, не требующие доступа к серверу.
- Если проблема сохраняется, попробуйте закрытие сессий или переход на Redis.
- Отключение 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-задач через сервер:
- Отключите встроенный WordPress cron:
define('DISABLE_WP_CRON', true);
- Добавьте системное задание 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-запросов и неоптимальных настроек серверной части. Следуя описанным выше шагам, вы сможете существенно снизить нагрузку на сервер и улучшить производительность сайта.
Если у вас возникли сложности с выполнением шагов, обратитесь к специалистам или хостинг-провайдеру за дополнительной помощью.