Рецепт от IT Аптека · Время лечения: 20–40 минут · Побочные эффекты: сайт начнёт работать
- Диагноз: почему твой WordPress тормозит как дизельный трактор в мороз
- Причины: 5 факторов, которые убивают скорость
- Рецепт: полная настройка Nginx FastCGI Cache на Ubuntu — от установки до боевого конфига
- Скрипт очистки кеша при публикации постов
- Осложнения: что делать, когда «не работает»
- Прогноз и профилактика
Диагноз: у тебя снова тормозит WordPress?
Картина знакомая: поставил WordPress, накидал плагинов, запустил. Сначала всё нормально. Потом — первые 500–1000 посетителей в сутки, и сервер начинает стонать. Time To First Byte (TTFB) — секунда. Две. PageSpeed Insights светит красным. Клиент звонит и говорит «сайт не грузится».
Ты лезешь в мониторинг, видишь 100% CPU на PHP-FPM, очередь запросов, и думаешь: «Ну и что теперь, брать сервер подороже?». Иногда — да. Но чаще — нет. Проблема не в железе. Проблема в том, что твой Nginx каждый раз тупо перекидывает запрос в PHP, PHP поднимает WordPress, WordPress идёт в базу, база думает, PHP рендерит HTML — и всё это ради страницы, которая не менялась последние три часа.
Лечим это кешем прямо на уровне Nginx. Он запоминает готовый HTML и отдаёт его следующим посетителям, не трогая PHP вообще. Называется это FastCGI Cache. После правильной настройки TTFB падает до 5–30 миллисекунд. Это не маркетинг — это физика.
- Готовый конфиг Nginx с FastCGI Cache для WordPress на Ubuntu
- Bash-скрипт для автоматической очистки кеша при публикации новых постов
- Чеклист проверки, что всё работает как надо
- Список типичных граблей — с готовыми командами для их обхода
Причины: почему WordPress без кеша — это боль
Давай без соплей. Вот что происходит при каждом запросе к незакешированному WordPress:
- PHP-FPM поднимает весь WordPress. Это десятки файлов, инициализация ядра, загрузка плагинов. Даже «лёгкий» сайт с 10 плагинами — это 50–100 мс только на bootstrap.
- WordPress идёт в MySQL. Главная страница — это легко 10–30 SQL-запросов. С плохо написанными плагинами — и все 100. База думает, блокировки, ждём.
- PHP генерирует HTML. Шаблон, виджеты, хуки, фильтры — всё это исполняется заново для каждого посетителя.
- Параллельные запросы убивают CPU. Пришло 50 человек одновременно — 50 процессов PHP, 50 соединений к базе. Сервер начинает задыхаться.
- Большинство страниц — статика по факту. Страница «О нас», статья в блоге, карточка товара — они меняются раз в день, если не реже. Но PHP честно пересобирает их каждый раз.
Рецепт: настройка FastCGI Cache в Nginx для WordPress на Ubuntu
Что нам понадобится
- Ubuntu 20.04 / 22.04 / 24.04 (на других дистрибутивах — аналогично, пути могут отличаться)
- Nginx (не Apache, не OpenLiteSpeed — именно Nginx)
- PHP-FPM (8.0, 8.1, 8.2, 8.3 — без разницы)
- WordPress уже установлен и работает
- Root или sudo-доступ к серверу
Если у тебя ещё нет связки Ubuntu + Nginx + PHP + WordPress — сначала разворачиваем стек с нуля (см. шаг 0). Если уже есть — пропускай сразу к шагу 1.
Шаг 0 (опционально): установка Nginx и PHP-FPM на Ubuntu с нуля
Если сервер голый — делаем так:
# Обновляем пакеты
sudo apt update && sudo apt upgrade -y
# Ставим Nginx
sudo apt install nginx -y
# Ставим PHP-FPM (пример для PHP 8.2)
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update
sudo apt install php8.2-fpm php8.2-mysql php8.2-xml php8.2-curl \
php8.2-gd php8.2-mbstring php8.2-zip php8.2-intl php8.2-bcmath -y
# Ставим MySQL
sudo apt install mysql-server -y
sudo mysql_secure_installation
# Проверяем, что всё запустилось
sudo systemctl status nginx
sudo systemctl status php8.2-fpm
sudo systemctl status mysql
Создаём базу для WordPress:
sudo mysql -u root -p
# Внутри MySQL:
CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'СЮДА_НОРМАЛЬНЫЙ_ПАРОЛЬ';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Качаем WordPress:
cd /var/www
sudo wget https://wordpress.org/latest.tar.gz
sudo tar -xzf latest.tar.gz
sudo mv wordpress /var/www/example.com
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
[СКРИНШОТ: вывод команды ls -la /var/www/example.com — должны видеть wp-admin, wp-content, wp-includes]
Шаг 1: создаём директорию для кеша Nginx
Nginx будет складывать закешированные ответы на диск. Даём ему место:
sudo mkdir -p /var/cache/nginx/fastcgi
sudo chown -R www-data:www-data /var/cache/nginx
sudo chmod -R 755 /var/cache/nginx
Шаг 2: настраиваем глобальный конфиг Nginx (nginx.conf)
Открываем основной конфиг:
sudo nano /etc/nginx/nginx.conf
Находим блок http { ... } и добавляем внутрь него (перед закрывающей фигурной скобкой) строки для FastCGI Cache:
# Добавить в блок http {}
# Зона кеша: 10m - это размер памяти под ключи кеша (не сами данные)
# 1d - хранить кеш максимум 1 день
# max_size=2g - максимум 2 гигабайта на диске под файлы кеша
fastcgi_cache_path /var/cache/nginx/fastcgi
levels=1:2
keys_zone=WORDPRESS:10m
inactive=1d
max_size=2g;
# Ключ кеша: URI + метод + хост - это уникальный ID каждой страницы
fastcgi_cache_key "$scheme$request_method$host$request_uri";
Сохраняем: Ctrl+O, Enter, Ctrl+X.
Шаг 3: создаём виртуальный хост Nginx для WordPress
Это центральная часть рецепта. Создаём конфиг сайта:
sudo nano /etc/nginx/sites-available/example.com
Вставляем весь конфиг целиком — с комментариями по каждому блоку:
# =============================================================
# Nginx конфиг для WordPress с FastCGI Cache
# Замени example.com на свой домен
# Замени php8.2-fpm на свою версию PHP
# =============================================================
# Переменная: пропускать кеш или нет
# По умолчанию - кешируем всё
map $http_cookie $skip_cache {
default 0;
# Залогиненные пользователи WordPress - мимо кеша
"~*wordpress_logged_in" 1;
# Пользователи, только что оставившие комментарий - мимо кеша
"~*comment_author" 1;
# Корзина WooCommerce - мимо кеша
"~*woocommerce_cart_hash" 1;
"~*woocommerce_items_in_cart" 1;
}
map $request_uri $skip_cache_uri {
default 0;
# Админка - без кеша
"~*/wp-admin/" 1;
# wp-login.php - без кеша
"~*/wp-login.php" 1;
# Страница оформления заказа WooCommerce - без кеша
"~*/checkout/" 1;
# Личный кабинет - без кеша
"~*/my-account/" 1;
# Корзина - без кеша
"~*/cart/" 1;
# wp-cron и xmlrpc - без кеша
"~*/wp-cron.php" 1;
"~*/xmlrpc.php" 1;
}
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
# Перенаправляем HTTP → HTTPS (раскомментируй после настройки SSL)
# return 301 https://$host$request_uri;
root /var/www/example.com;
index index.php index.html;
# Логи
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
# Лимиты и безопасность
client_max_body_size 64M;
server_tokens off;
# --------------------------------------------------------
# Заголовок X-Cache-Status - чтобы видеть, из кеша или нет
# --------------------------------------------------------
add_header X-Cache-Status $upstream_cache_status;
# --------------------------------------------------------
# Статика отдаём напрямую - PHP не нужен
# --------------------------------------------------------
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf|webp|avif)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
try_files $uri =404;
}
# --------------------------------------------------------
# Скрываем чувствительные файлы
# --------------------------------------------------------
location ~ /\. {
deny all;
}
location ~ /wp-config.php {
deny all;
}
location = /xmlrpc.php {
deny all;
}
# --------------------------------------------------------
# Основной роутинг WordPress (Permalink)
# --------------------------------------------------------
location / {
try_files $uri $uri/ /index.php?$args;
}
# --------------------------------------------------------
# PHP-FPM + FastCGI Cache
# --------------------------------------------------------
location ~ \.php$ {
# Защита от Nginx + PHP-FPM path traversal
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Сокет PHP-FPM (замени версию если нужно)
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
# Таймауты
fastcgi_read_timeout 300;
fastcgi_connect_timeout 60;
fastcgi_send_timeout 300;
# Буферы (ускоряют отдачу)
fastcgi_buffer_size 128k;
fastcgi_buffers 256 16k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
# =====================================================
# FastCGI CACHE - главная магия
# =====================================================
# Используем зону WORDPRESS из nginx.conf
fastcgi_cache WORDPRESS;
# Кешируем 200 и 301 ответы на 1 час
fastcgi_cache_valid 200 301 1h;
# 404 - на 15 минут
fastcgi_cache_valid 404 15m;
# Логика пропуска кеша
fastcgi_cache_bypass $skip_cache $skip_cache_uri;
fastcgi_no_cache $skip_cache $skip_cache_uri;
# Если бэкенд упал - отдаём устаревший кеш (stale)
fastcgi_cache_use_stale error timeout updating http_500 http_503;
# Пока кеш обновляется - отвечает одним запросом к PHP, остальным - из старого кеша
fastcgi_cache_lock on;
fastcgi_cache_lock_timeout 5s;
# Фоновое обновление кеша (не блокирует пользователя)
fastcgi_cache_background_update on;
# Метод кеширования - только GET и HEAD
fastcgi_cache_methods GET HEAD;
# Передаём реальный IP если за балансировщиком
fastcgi_param HTTP_X_FORWARDED_FOR $proxy_add_x_forwarded_for;
}
# --------------------------------------------------------
# Кеш для wp-cron - отключаем стандартный, запускаем через crontab
# --------------------------------------------------------
location = /wp-cron.php {
internal;
}
}
# =============================================================
# HTTPS блок (раскомментируй после certbot)
# =============================================================
# server {
# listen 443 ssl http2;
# listen [::]:443 ssl http2;
# server_name example.com www.example.com;
#
# ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_prefer_server_ciphers on;
#
# # ... остальное - копируй из HTTP-блока выше ...
# }
Активируем сайт и проверяем конфиг:
# Создаём симлинк
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
# Удаляем дефолтный сайт, если мешает
sudo rm -f /etc/nginx/sites-enabled/default
# Проверяем синтаксис конфига - ОБЯЗАТЕЛЬНО перед перезапуском
sudo nginx -t
# Если всё чисто - перезапускаем
sudo systemctl reload nginx
[СКРИНШОТ: вывод nginx -t — должно быть «syntax is ok» и «test is successful»]
Шаг 4: настраиваем PHP-FPM под WordPress
PHP-FPM по умолчанию настроен на «среднее» значение. Поправим его под WordPress:
sudo nano /etc/php/8.2/fpm/pool.d/www.conf
Находим и правим эти параметры (или добавляем если нет):
; Количество одновременных PHP-процессов - считай по формуле:
; pm.max_children = (RAM в МБ - 256) / 50
; Пример для 2GB RAM: (2048 - 256) / 50 = ~35
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 8
pm.max_requests = 500
; Статус PHP-FPM (полезно для мониторинга)
pm.status_path = /status
; Таймаут запроса (секунды)
request_terminate_timeout = 300
Перезапускаем PHP-FPM:
sudo systemctl restart php8.2-fpm
Шаг 5: устанавливаем WordPress через WP-CLI
Если WordPress ещё не установлен — ставим через WP-CLI. Это быстрее и надёжнее, чем веб-установщик.
# Ставим WP-CLI
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
wp --info
# Переходим в директорию WordPress
cd /var/www/example.com
# Создаём wp-config.php
sudo -u www-data wp config create \
--dbname=wordpress \
--dbuser=wpuser \
--dbpass=СЮДА_НОРМАЛЬНЫЙ_ПАРОЛЬ \
--dbhost=localhost \
--dbcharset=utf8mb4
# Устанавливаем WordPress
sudo -u www-data wp core install \
--url=http://example.com \
--title="Мой сайт" \
--admin_user=admin \
--admin_password=СЛОЖНЫЙ_ПАРОЛЬ \
--admin_email=admin@example.com \
--skip-email
[СКРИНШОТ: вывод wp core install — «Success: WordPress installed successfully.»]
Шаг 6: скрипт автоочистки кеша при публикации постов
По факту, это самый важный шаг после настройки кеша. Ты опубликовал новую статью — а посетители ещё час видят старую главную страницу. Это лечится двумя способами: плагином или скриптом.
Вариант А: плагин Nginx Cache (для простых сайтов)
sudo -u www-data wp plugin install nginx-cache --activate
Идёшь в WordPress → Настройки → Nginx Cache, указываешь путь /var/cache/nginx/fastcgi — и плагин будет чистить кеш при обновлении записей.
Но у плагина есть ограничения: он чистит весь кеш целиком, что неэффективно. Для нагруженных сайтов — смотри Вариант Б.
Вариант Б: bash-скрипт точечной очистки кеша
Создаём скрипт:
sudo nano /usr/local/bin/nginx-cache-purge.sh
#!/bin/bash
# nginx-cache-purge.sh
# Скрипт точечной очистки FastCGI Cache Nginx для WordPress
# Вызывается из wp-config.php или cron
CACHE_DIR="/var/cache/nginx/fastcgi"
LOG_FILE="/var/log/nginx/cache-purge.log"
DATE=$(date '+%Y-%m-%d %H:%M:%S')
# Если передан URI - чистим только конкретную страницу
if [ -n "$1" ]; then
URI="$1"
echo "[$DATE] Purge URI: $URI" >> "$LOG_FILE"
# Вычисляем ключ кеша: схема + метод + хост + URI
# По умолчанию Nginx кеширует GET-запросы
CACHE_KEY="httpGETyourdomain.com${URI}"
CACHE_FILE=$(echo -n "$CACHE_KEY" | md5sum | awk '{print $1}')
# Ищем файл по первым символам хеша (levels=1:2)
SUBDIR1="${CACHE_FILE: -1}"
SUBDIR2="${CACHE_FILE: -3:2}"
FULL_PATH="${CACHE_DIR}/${SUBDIR1}/${SUBDIR2}/${CACHE_FILE}"
if [ -f "$FULL_PATH" ]; then
rm -f "$FULL_PATH"
echo "[$DATE] Deleted: $FULL_PATH" >> "$LOG_FILE"
else
echo "[$DATE] Cache file not found: $FULL_PATH" >> "$LOG_FILE"
fi
else
# Без аргументов - чистим весь кеш
echo "[$DATE] Full cache purge started" >> "$LOG_FILE"
find "$CACHE_DIR" -type f -delete
echo "[$DATE] Full cache purge done" >> "$LOG_FILE"
fi
sudo chmod +x /usr/local/bin/nginx-cache-purge.sh
sudo chown www-data:www-data /usr/local/bin/nginx-cache-purge.sh
Тестируем:
# Полная очистка кеша
sudo -u www-data /usr/local/bin/nginx-cache-purge.sh
# Проверяем лог
tail -20 /var/log/nginx/cache-purge.log
Вариант В: через WordPress хук (для разработчиков)
Добавляем в functions.php темы или в плагин-мю:
# Создаём mu-plugin для автоочистки кеша
sudo nano /var/www/example.com/wp-content/mu-plugins/nginx-cache-clear.php
<?php
/**
* MU Plugin: Nginx FastCGI Cache Purge
* Очищает кеш при сохранении/обновлении записей
*/
// При публикации или обновлении поста
add_action('save_post', 'nginx_cache_purge_on_save', 10, 2);
function nginx_cache_purge_on_save($post_id, $post) {
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
if ($post->post_status !== 'publish') return;
// Чистим весь кеш (можно сделать точечным - по URL поста)
shell_exec('sudo -u www-data /usr/local/bin/nginx-cache-purge.sh 2>/dev/null');
// Логируем
error_log('[Nginx Cache] Purged on post save: ' . $post_id);
}
// При смене темы или настроек
add_action('switch_theme', 'nginx_cache_full_purge');
add_action('update_option_blogdescription', 'nginx_cache_full_purge');
function nginx_cache_full_purge() {
shell_exec('sudo -u www-data /usr/local/bin/nginx-cache-purge.sh 2>/dev/null');
}
sudo chown www-data:www-data /var/www/example.com/wp-content/mu-plugins/nginx-cache-clear.php
Шаг 7: SSL через Let’s Encrypt (Certbot)
Кеш работает и по HTTP, но без HTTPS сайт теряет позиции в поиске. Ставим сертификат:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d example.com -d www.example.com
Certbot сам пропишет SSL в конфиге Nginx. После этого раскомментируй HTTPS-блок из шага 3 и проверь, что редирект с HTTP работает.
# Автообновление сертификата - certbot уже добавляет таймер systemd
sudo systemctl status certbot.timer
Шаг 8: проверяем, что кеш работает
Самый быстрый способ — смотреть заголовок X-Cache-Status:
# Первый запрос - MISS (PHP отработал, результат закешировался)
curl -I http://example.com | grep X-Cache-Status
# Второй запрос - должен быть HIT (отдал из кеша, PHP не трогали)
curl -I http://example.com | grep X-Cache-Status
[СКРИНШОТ: вывод curl с заголовком X-Cache-Status: HIT]
Значения заголовка:
- HIT — страница из кеша. PHP не трогали. Всё работает.
- MISS — первый запрос, кеш только заполняется. Норма.
- BYPASS — запрос попал под условие пропуска (залогиненный пользователь, корзина и т.д.).
- EXPIRED — кеш устарел, идёт обновление.
- STALE — бэкенд упал, отдаётся старый кеш. Жить можно.
Шаг 9 (бонус): настройка wp-cron через системный cron
WordPress по умолчанию запускает wp-cron при каждом визите — это лишняя нагрузка. Отключаем и переводим на системный cron:
# Добавляем в wp-config.php
sudo -u www-data wp config set DISABLE_WP_CRON true --raw
# Добавляем задачу в crontab
sudo crontab -u www-data -e
# Добавляем строку:
*/5 * * * * cd /var/www/example.com && php wp-cron.php > /dev/null 2>&1
Осложнения: что делать, если не работает
- Всегда начинай с
sudo nginx -t— синтаксические ошибки в конфиге убивают всё - Смотри логи:
sudo tail -50 /var/log/nginx/error.log - Смотри логи PHP-FPM:
sudo tail -50 /var/log/php8.2-fpm.log - Проверяй права на кеш:
ls -la /var/cache/nginx/— владелец должен быть www-data
Проблема: Nginx не запускается после изменения конфига
# Проверяем синтаксис
sudo nginx -t
# Смотрим подробные ошибки
sudo journalctl -xeu nginx.service | tail -30
Типичные причины: лишняя запятая в конфиге, неправильный путь к сокету PHP-FPM, указана зона кеша которой нет в nginx.conf.
Проблема: 502 Bad Gateway
# Проверяем, что PHP-FPM запущен
sudo systemctl status php8.2-fpm
# Проверяем путь к сокету
ls -la /run/php/
# Должен быть файл php8.2-fpm.sock
# Если сокета нет - перезапускаем PHP-FPM
sudo systemctl restart php8.2-fpm
Если сокет есть, но 502 продолжается — проверяем права:
# Nginx и PHP-FPM должны использовать одного пользователя
grep "^user" /etc/nginx/nginx.conf
grep "^user\|^listen.owner" /etc/php/8.2/fpm/pool.d/www.conf
Проблема: X-Cache-Status всегда MISS
Кеш не записывается. Проверяем:
# Права на директорию кеша
ls -la /var/cache/nginx/fastcgi/
# Ставим диагностику: смотрим, появляются ли файлы после запросов
watch -n 1 'find /var/cache/nginx/fastcgi -type f | wc -l'
# В соседнем терминале:
curl -s http://example.com > /dev/null
curl -s http://example.com > /dev/null
# Если файлы не появляются - проверяем, что зона WORDPRESS объявлена в nginx.conf
grep -n "fastcgi_cache_path" /etc/nginx/nginx.conf
Проблема: X-Cache-Status всегда BYPASS
Кеш обходится для всех запросов. Смотрим в cookies:
# Проверяем, нет ли в браузере WordPress-куки
curl -v --cookie "" http://example.com 2>&1 | grep -i "x-cache\|cookie\|bypass"
# Если ты залогинен в WP-Admin - выйди и проверь из инкогнито-вкладки
Проблема: сайт отдаёт устаревший контент после публикации поста
# Ручная очистка кеша
sudo -u www-data /usr/local/bin/nginx-cache-purge.sh
# Проверяем, работает ли mu-plugin
sudo -u www-data wp eval 'do_action("save_post", 1, get_post(1));'
# Проверяем права на скрипт очистки
ls -la /usr/local/bin/nginx-cache-purge.sh
# Должно быть: -rwxr-xr-x 1 www-data www-data
Проблема: WooCommerce — корзина и checkout кешируются
Это критично. Проверяем, что в конфиге прописаны исключения:
grep -A5 "skip_cache_uri" /etc/nginx/sites-available/example.com
# Должны видеть: checkout, cart, my-account
# Также добавляем исключение по cookie WooCommerce
grep -A10 "skip_cache" /etc/nginx/sites-available/example.com
# Должны видеть: woocommerce_cart_hash, woocommerce_items_in_cart
Проблема: WordPress не видит реальный IP пользователя (все запросы с 127.0.0.1)
sudo nano /etc/nginx/sites-available/example.com
# Добавить в server {} блок:
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
Прогноз: что мы сделали и чего ждать
Итог
Короче, по факту ты сделал следующее:
- Настроил Nginx FastCGI Cache с зоной WORDPRESS
- Прописал умные исключения — кеш обходит залогиненных пользователей, WooCommerce, корзину и админку
- Настроил PHP-FPM с адекватными лимитами под реальную нагрузку
- Добавил скрипт и хук для очистки кеша при публикации постов
- Отключил wp-cron от посетителей и перевёл на системный cron
- TTFB для закешированных страниц: 5–50 мс вместо 500–3000 мс
- CPU на PHP-FPM: снижение в 10–50 раз для типичного блога/новостного сайта
- Сайт выдерживает в 20–50 раз больше одновременных посетителей без апгрейда железа
- При падении бэкенда (PHP или MySQL) — посетители получают стейл-кеш, а не белый экран
Профилактика: что делать дальше
- Настрой мониторинг TTFB — через UptimeRobot, BetterUptime или Zabbix. Если TTFB вырос — первым делом смотри, не переполнился ли кеш и не сломался ли скрипт очистки.
- Следи за размером кеша —
du -sh /var/cache/nginx/fastcgi/. Если растёт бесконтрольно — уменьшиmax_sizeилиinactiveв конфиге зоны. - Обновляй PHP — каждая минорная версия PHP быстрее предыдущей. PHP 8.3 быстрее 8.0 примерно на 15–20% по бенчмаркам.
- Используй OPcache — это кеш скомпилированного PHP-кода. Проверяй:
php -r "phpinfo();" | grep opcache.enable. Должно бытьOn.
# Проверяем OPcache одной командой
php -r "echo ini_get('opcache.enable') ? 'OPcache включён' : 'OPcache ВЫКЛЮЧЕН - срочно включи!';"
# Если выключен - правим php.ini
sudo nano /etc/php/8.2/fpm/php.ini
# Находим и ставим:
# opcache.enable=1
# opcache.memory_consumption=256
# opcache.interned_strings_buffer=16
# opcache.max_accelerated_files=10000
# opcache.revalidate_freq=2
sudo systemctl restart php8.2-fpm
dd if=/dev/zero of=/tmp/test bs=1M count=512 oflag=dsync — меньше 200 MB/s на запись означает HDD или медленный SSD.Вопросы и обратная связь
Если что-то пошло не так — пиши в комментарии. Описывай: дистрибутив, версию Nginx, версию PHP и что конкретно выводит nginx -t и curl -I. С этим набором данных лечится 90% случаев.
Оставайтесь на связи
Рецепты от IT-боли. Без воды, без рекламы, без маркетинговой шелухи.
Подписаться на IT-Аптеку →


