Как подготовить WordPress к высокой нагрузке: 100 000 посетителей в день
1. Архитектура и балансировка нагрузки
При 100 000 уникальных посетителей в день один сервер быстро превратится в бутылочное горлышко. Решение – распределить трафик между несколькими узлами.
1.1 Выбор стратегии
- DNS‑резолвинг – простой, но мало гибок.
- Аппаратный/облачный LB (AWS ELB, Cloudflare Load Balancer, Nginx + keepalive).
- Round‑Robin + Sticky Sessions – сохраняет сессию пользователя на одном узле.
1.2 Пример конфигурации Nginx как балансировщика
upstream wp_backend {
ip_hash; # сохраняет сессию
server 10.0.0.101:80;
server 10.0.0.102:80;
server 10.0.0.103:80;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://wp_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
После настройки балансировщика можно масштабировать WordPress‑узлы горизонтально.
2. Кеширование на уровне сервера и приложений
Кеш – главный способ снизить нагрузку на PHP и MySQL.
2.1 HTTP‑кеш (FastCGI, Nginx, Varnish)
Для статических страниц включаем fastcgi_cache в Nginx:
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=WP:100m inactive=60m;
location ~ .php$ {
fastcgi_cache WP;
fastcgi_cache_valid 200 301 302 10m;
fastcgi_cache_use_stale error timeout updating;
fastcgi_pass php-fpm;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
2.2 Объектный кеш (Redis или Memcached)
Устанавливаем redis и подключаем через плагин Redis Object Cache. В wp-config.php добавляем:
define('WP_REDIS_HOST', '127.0.0.1');
define('WP_REDIS_PORT', 6379);
define('WP_CACHE_KEY_SALT', 'example.com_');
Объектный кеш ускорит запросы WP_Query, мета‑данные и опции.
3. Очереди и асинхронные задачи
Отправка писем, генерация миниатюр и импорт больших CSV‑файлов лучше выполнять в фоне.
3.1 WP‑Cron vs System Cron
Отключаем встроенный WP‑Cron и заменяем его системным crontab:
# В wp-config.php
define('DISABLE_WP_CRON', true);
Затем в crontab -e добавляем:
*/5 * * * * wget -q -O - https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1
3.2 Очереди RabbitMQ + WP Background Processing
Для тяжёлых задач ставим php-amqplib/php-amqplib и пишем воркер:
channel();
$channel->queue_declare('wp_tasks', false, true, false, false);
while (true) {
$msg = $channel->basic_get('wp_tasks');
if ($msg) {
// обработка задачи
// пример: wp_insert_post([...]);
$channel->basic_ack($msg->delivery_info['delivery_tag']);
}
sleep(1);
}
?>
Такой подход гарантирует, что пользовательский запрос не будет ждать выполнения ресурсоёмкой операции.
4. CDN и статический контент
Перенос изображений, CSS, JS и шрифтов в CDN уменьшает latency и снимает нагрузку с веб‑сервера.
4.1 Выбор провайдера
Популярные варианты: Cloudflare, KeyCDN, Amazon CloudFront. Для WordPress удобно использовать плагин WP Offload Media, который автоматически переписывает URL‑ы медиа‑файлов.
4.2 Настройка Cache‑Control заголовков
location ~* .(?:css|js|jpg|jpeg|png|gif|svg|woff2?)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
Не забудьте включить ленивую загрузку, чтобы изображения подгружались только при скроллинге.
5. Оптимизация базы данных
MySQL становится узким местом, если запросы не индексированы.
5.1 Индексация таблиц wp_posts и wp_postmeta
ALTER TABLE wp_posts ADD INDEX idx_post_type_status (post_type, post_status);
ALTER TABLE wp_postmeta ADD INDEX idx_meta_key (meta_key(191));
5.2 Очистка «мусора»
Регулярно удаляем ревизии, автосохранения и спам‑комментарии. Плагин WP‑Optimize делает это в один клик.
5.3 Перенос аналитических запросов в отдельный реплика‑сервер
В wp-config.php указываем реплику для чтения:
define('DB_READ_REPLICA_HOST', '10.0.0.201');
define('DB_WRITE_HOST', '10.0.0.200');
Библиотека wpdb автоматически будет использовать реплику при вызовах get_results().
6. Тонкая настройка сервера
Существенное влияние на производительность оказывают параметры PHP‑FPM, MySQL и ОС.
6.1 PHP‑FPM pool
pm = dynamic
pm.max_children = 100
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
6.2 MySQL‑tuning (innodb_buffer_pool_size)
Для 8 ГБ ОЗУ рекомендуется установить innodb_buffer_pool_size=4G. Это ускорит чтение индексов.
6.3 OS‑level: TCP‑tuning
net.core.somaxconn = 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
Эти параметры позволяют обслуживать больше одновременных соединений.
Для полной картины по мобильной оптимизации обратитесь к статье Mobile‑friendly WordPress. Если нужен резервный план, прочитайте автоматический бэкап. А для быстрой работы редактора Gutenberg используйте Reusable blocks.
❓ Часто задаваемые вопросы
Какой тип кеширования наиболее эффективен при 100 000 запросах в день?
Комбинация HTTP‑кеша (FastCGI/Varnish) и объектного кеша (Redis) дает лучший результат: HTTP‑кеш обслуживает статический контент, а Redis ускоряет динамические запросы WordPress.
Нужен ли отдельный сервер базы данных?
Да. При такой нагрузке лучше вынести MySQL на отдельный сервер или использовать репликацию: один сервер пишет, а несколько – читают, тем самым уменьшая конкуренцию за ресурсы.
Можно ли использовать бесплатный CDN?
Бесплатные варианты, такие как Cloudflare Free, подходят для базовой доставки статических файлов, но для полного off‑load медиа‑контента рекомендуется платный план или специализированный CDN.
Как избежать потери писем при обработке в фоне?
Перенесите отправку писем в очередь (RabbitMQ, Redis Queue) и обрабатывайте их отдельным воркером. Это гарантирует, что пользовательский запрос завершится быстро, а письмо будет отправлено позже.