Диагностика проблемы: почему не отправляются URL при массовом обновлении
Частая ситуация — при массовом обновлении контента (например, изменение статуса большого числа постов, обновление метаданных или массовый импорт) автоматическая отправка URL в IndexNow не срабатывает или срабатывает не полностью. Это связано с ограничениями по времени выполнения PHP, лимитами API IndexNow и особенностями работы хуков WordPress.
Чтобы диагностировать проблему, проверьте:
- Логи ошибок PHP и сервера — нет ли таймаутов или превышения лимитов памяти;
- Логи запросов к API IndexNow — успешны ли ответы сервера поисковиков (код 200);
- Используются ли правильные хуки для отправки URL (например,
save_post,transition_post_status); - Не блокируются ли запросы к IndexNow плагинами кэширования или безопасностью.
Пошаговое решение проблемы массовой отправки URL через очереди и пакетную обработку
1. Создаем очередь URL для отправки
При массовом обновлении добавляем URL в очередь, вместо немедленной отправки. Это позволяет избежать таймаутов и блокировок.
function indexnow_enqueue_url_for_sending($url) {
global $wpdb;
$table_name = $wpdb->prefix . 'indexnow_queue';
// Создаем таблицу, если не существует
$wpdb->query("CREATE TABLE IF NOT EXISTS $table_name (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
url VARCHAR(255) NOT NULL,
sent TINYINT(1) DEFAULT 0,
PRIMARY KEY(id),
UNIQUE KEY url (url)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;");
$wpdb->replace($table_name, ['url' => $url, 'sent' => 0]);
}2. Добавляем URL в очередь при массовом обновлении постов
Используем хук save_post и проверяем, что массовое обновление происходит (например, при импорте или изменении статуса).
add_action('save_post', function($post_id, $post, $update) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if ($post->post_status !== 'publish') return; // Отправляем только опубликованные
$url = get_permalink($post_id);
indexnow_enqueue_url_for_sending($url);
}, 10, 3);3. Создаем WP-Cron задачу для пакетной отправки URL
Для отправки URL из очереди используем Cron, отправляя URL пакетами (например, по 20 штук), чтобы не перегружать сервер и не превышать лимиты.
function indexnow_send_batch_urls() {
global $wpdb;
$table_name = $wpdb->prefix . 'indexnow_queue';
$batch_size = 20;
$urls = $wpdb->get_col("SELECT url FROM $table_name WHERE sent = 0 LIMIT $batch_size");
if (empty($urls)) return;
$endpoint = 'https://api.indexnow.org/indexnow?key=ВАШ_КЛЮЧ_API';
$response = wp_remote_post($endpoint, [
'body' => json_encode(['host' => parse_url(home_url(), PHP_URL_HOST), 'key' => 'ВАШ_КЛЮЧ_API', 'keyLocation' => home_url('/indexnow-key.txt'), 'urlList' => $urls]),
'headers' => ['Content-Type' => 'application/json'],
'timeout' => 10,
]);
if (is_wp_error($response)) {
error_log('IndexNow отправка URL ошибка: ' . $response->get_error_message());
return;
}
$code = wp_remote_retrieve_response_code($response);
if ($code === 200) {
foreach ($urls as $url) {
$wpdb->update($table_name, ['sent' => 1], ['url' => $url]);
}
} else {
error_log('IndexNow отправка URL неверный код ответа: ' . $code);
}
}
// Регистрируем задачу Cron
add_action('indexnow_send_urls_cron', 'indexnow_send_batch_urls');
if (!wp_next_scheduled('indexnow_send_urls_cron')) {
wp_schedule_event(time(), 'minute', 'indexnow_send_urls_cron');
}Проверка результата после внедрения
- В базе данных WordPress в таблице
{prefix}_indexnow_queueURL меняют статус сsent=0наsent=1после успешной отправки; - В логах сервера отсутствуют ошибки, связанные с отправкой IndexNow;
- Проверка ответа API IndexNow — код 200 и отсутствие ошибок;
- В панели поисковиков (Bing, Yandex) в разделе IndexNow наблюдается увеличивающийся поток отправленных URL;
- При массовом обновлении сайта новые URL корректно отправляются в течение нескольких минут (зависит от Cron).
Частые ошибки и как их исправить
- Таймауты PHP при массовой отправке. Решение: использовать очередь и пакетную отправку через Cron, как показано выше.
- Дублирование URL в очереди. Сделайте уникальный индекс по URL в таблице базы, чтобы избежать повторной отправки.
- Отсутствие ключа API или неправильный ключ. Проверьте правильность ключа и наличие файла
indexnow-key.txtв корне сайта. - Плагины кэширования блокируют запросы. Исключите URL API IndexNow из кэширования или настройте исключения.
- Отсутствие Cron задач. Проверьте, что WP-Cron работает (например, плагином WP Crontrol) или настройте системный cron.
Практические советы по безопасности и производительности
- Храните ключ API IndexNow в
wp-config.phpчерез константу, а не в открытом коде. - Ограничьте частоту отправки URL через очередь, чтобы не превысить лимиты IndexNow.
- Используйте транзиенты или кеш для предотвращения повторных попыток отправки одного и того же URL в течение короткого времени.
- Регулярно очищайте таблицу очереди от отправленных URL, чтобы не засорять базу.
- Тестируйте отправку URL на тестовом сайте перед внедрением на боевой.
Сравнение вариантов реализации массовой отправки URL в IndexNow
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Немедленная отправка в save_post | Отправка сразу при сохранении поста | Простота реализации | Высокая нагрузка при массовых изменениях, таймауты |
| Очередь + Cron | Добавление URL в очередь, пакетная отправка через Cron | Масштабируемость, стабильность, контроль нагрузки | Сложнее реализовать, задержка в отправке |
| Использование внешних очередей (Redis, RabbitMQ) | Отдельные сервисы очередей | Высокая производительность, надежность | Требует инфраструктуры, сложности в настройке |