Дата публикации документа: 22-02-2026
Дата обновления документа: 22-02-2026
Документ ориентирован для решения вопросов:
Содержание:
innodb_buffer_poolhuge_code_pages| CMS / Фреймворк | Что можно применить |
|---|---|
| OpenCart | Всё: MySQL, Apache, PHP, кэширование, прогрев |
| WordPress | InnoDB, OPcache, .htaccess, прогрев, Brotli/Gzip |
| Magento | MySQL, PHP-FPM, OPcache, кэширование, Nginx (аналог) |
| Laravel / Symfony | OPcache, PHP-FPM, кэширование маршрутов, прогрев |
Все конфигурации разработаны и многократно протестированы на PHP 7.1 в production-среде.
Совместимость с версиями PHP:
Решения не рекомендуются для PHP ниже 7.1 из-за отсутствия поддержки ключевых оптимизаций и известных уязвимостей безопасности.
Рекомендуемые аппаратные ресурсы: NVMe SSD, 6+ CPU, от 12 ГБ RAM
/etc/my.cnf)По умолчанию многие CMS используют MyISAM. Рекомендуется перевести все таблицы на InnoDB:
ALTER TABLE oc_product ENGINE=InnoDB;
ALTER TABLE oc_product_description ENGINE=InnoDB;
ALTER TABLE oc_category ENGINE=InnoDB;
ALTER TABLE oc_order ENGINE=InnoDB;
-- Повторить для всех таблиц
Почему это важно:
innodb_buffer_pool — кэширует данные в RAMПроверить тип таблиц:
SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'your_database';
Раз в неделю — оптимизировать таблицы для дефрагментации и освобождения места:
# Через mysqlcheck
mysqlcheck -u root -p --optimize --all-databases
# Или для одной БД
mysqlcheck -u root -p your_database_name --optimize --all-tables
Можно добавить в cron:
0 3 * * 0 /usr/bin/mysqlcheck -u root -p'password' your_db --optimize --silent
Для InnoDB OPTIMIZE TABLE перестраивает таблицу и индексы — полезно после массовых
удалений/обновлений.
После запуска OPTIMIZE TABLE для InnoDB-таблиц, phpMyAdmin показывает:
SQL-запрос успешно выполнен.
OPTIMIZE TABLE `oc_product`, `oc_category`, `oc_order`, `oc_customer`, `oc_cart`;
+---------------------+----------+----------+-----------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+---------------------+----------+----------+-----------------------------------------------------------+
| mydb.oc_product | optimize | note | Table does not support optimize, doing recreate + analyze |
| mydb.oc_product | optimize | status | OK |
| mydb.oc_category | optimize | note | Table does not support optimize, doing recreate + analyze |
| mydb.oc_category | optimize | status | OK |
| mydb.oc_order | optimize | note | Table does not support optimize, doing recreate + analyze |
| mydb.oc_order | optimize | status | OK |
| mydb.oc_customer | optimize | note | Table does not support optimize, doing recreate + analyze |
| mydb.oc_customer | optimize | status | OK |
| mydb.oc_cart | optimize | note | Table does not support optimize, doing recreate + analyze |
| mydb.oc_cart | optimize | status | OK |
+---------------------+----------+----------+-----------------------------------------------------------+
Что это означает:
Table does not support optimize — InnoDB не имеет встроенного OPTIMIZE, поэтому MySQL
эмулирует его через ALTER TABLE ... ENGINE=InnoDB (recreate)recreate + analyze — таблица пересоздаётся, а статистика индексов обновляетсяstatus: OK — операция прошла успешноВажно: Сделать резервную копию. OPTIMIZE TABLE для InnoDB требует
временного места на диске (примерно = размер таблицы) и блокирует таблицу на время операции. Рекомендуется
выполнять в период низкой нагрузки.
[mysqld]
# Привязка к локальному интерфейсу
bind-address = 127.0.0.1
# Максимальный размер пакета (для больших запросов и импорта)
max_allowed_packet = 64M
# Размер стека потока
thread_stack = 256K
# Логирование медленных запросов
slow_query_log = /var/log/mysql/mysql-slow.log
long_query_time = 1
# Таймауты соединений
interactive_timeout = 60
wait_timeout = 60
# Защита от флуда подключений
max_connect_errors = 10000
max_connections = 300
thread_cache_size = 100
thread_concurrency = 6
# Путь к данным
datadir = /var/lib/mysql
socket = /var/run/mysqld/mysql.sock
symbolic-links = 0
# Движок по умолчанию — InnoDB
default-storage-engine = InnoDB
# Отдельный файл на таблицу — удобно для обслуживания
innodb_file_per_table = 1
# Кэш открытых таблиц
table_open_cache = 2000
table_definition_cache = 600
open_files_limit = 10000
# === InnoDB: основные настройки производительности ===
# Буферный пул — 70–80% от RAM (8G при 12G)
innodb_buffer_pool_size = 8G
# Разделение пула на экземпляры (по числу CPU)
innodb_buffer_pool_instances = 6
# Запись лога раз в секунду (не после каждой транзакции)
innodb_flush_log_at_trx_commit = 2
# Прямая запись на диск, минуя кэш ОС
innodb_flush_method = O_DIRECT
# Адаптивный хеш-индекс — ускоряет частые чтения
innodb_adaptive_hash_index = ON
# Размер файла журнала транзакций (больше = меньше I/O)
innodb_log_file_size = 2G
# Буфер лога в памяти
innodb_log_buffer_size = 256M
# Сохранение "горячего" кэша при остановке
innodb_buffer_pool_dump_at_shutdown = ON
# Загрузка кэша при старте
innodb_buffer_pool_load_at_startup = ON
# Пропускная способность I/O (NVMe)
innodb_io_capacity = 2000
# Параллельные потоки чтения/записи
innodb_read_io_threads = 8
innodb_write_io_threads = 8
# Время ожидания блокировки
innodb_lock_wait_timeout = 120
# Макс. процент "грязных" страниц
innodb_max_dirty_pages_pct = 70
# Адаптивная фоновая запись
innodb_adaptive_flushing = ON
# Защита от случайного сканирования
innodb_old_blocks_time = 1000
# Отключение сбора мета-статистики
innodb_stats_on_metadata = OFF
# Уровень изоляции — меньше блокировок
transaction-isolation = READ-COMMITTED
# Кодировка по умолчанию
collation-server = utf8_general_ci
init-connect = 'SET NAMES utf8'
character-set-server = utf8
# Query Cache — устарел, отключаем полностью
query_cache_type = 0
query_cache_size = 0
# Временные таблицы в памяти (важно для JOIN, ORDER BY)
tmp_table_size = 512M
max_heap_table_size = 512M
# Директория временных файлов (лучше на tmpfs)
tmpdir = /tmp
/etc/httpd/conf/httpd.confServerRoot "/etc/httpd"
Listen 80
# Загрузка модулей
Include conf.modules.d/*.conf
User apache
Group apache
# Безопасность
ServerSignature Off
ServerTokens Prod
# Корневой доступ — запрещён
<Directory />
AllowOverride None
Require all denied
</Directory>
# MPM Worker — потоковый режим (рекомендуется)
<IfModule mpm_worker_module>
StartServers 6
MinSpareThreads 50
MaxSpareThreads 100
ThreadsPerChild 25
MaxRequestWorkers 300
ServerLimit 12
MaxRequestsPerChild 0
</IfModule>
# Fallback: Prefork (если Worker недоступен)
<IfModule mpm_prefork_module>
StartServers 10
MinSpareServers 5
MaxSpareServers 20
MaxRequestWorkers 300
MaxConnectionsPerChild 5000
</IfModule>
DocumentRoot "/var/www/html"
# Основной каталог сайта — без .htaccess
<Directory "/var/www">
AllowOverride None
Require all granted
</Directory>
# Только для нужных директорий — разрешить .htaccess
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Индексные файлы
<IfModule dir_module>
DirectoryIndex index.php index.html index.htm
</IfModule>
# Запрет доступа ко всем .ht* файлам
<Files ".ht*">
Require all denied
</Files>
# Логи
ErrorLog "logs/error_log"
LogLevel warn
# Формат логов
LogFormat "%v:%p %a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
CustomLog "logs/access_log" combined
# Отдача файлов ядром ОС — ускоряет статику
EnableSendfile on
# Подключение дополнительных конфигураций
IncludeOptional conf.d/*.conf
IncludeOptional vhost.d/*.conf
# Таймаут Keep-Alive — быстрое освобождение соединений
KeepAliveTimeout 1
/etc/httpd/vhost.d/site.conf<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /path/to/site
# Обработка PHP через PHP-FPM
<IfModule proxy_fcgi_module>
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php-fpm/php-site.sock|fcgi://localhost/path/to/site"
</FilesMatch>
</IfModule>
<Directory "/path/to/site">
AllowOverride All
Require all granted
</Directory>
# Доступ к .well-known для Let's Encrypt
<Directory '/path/to/site/.well-known'>
Options Indexes FollowSymLinks Includes ExecCGI
ForceType 'text/plain'
AddDefaultCharset Off
Require all granted
</Directory>
CustomLog /path/to/logs/access.log combined
ErrorLog /path/to/logs/error.log
DirectoryIndex index.php index.html index.htm
</VirtualHost>
Размещается в корне сайта. Управляет URL, безопасностью, заголовками и кэшированием.
# Исправление дублирующихся & в query-строке
RewriteCond %{QUERY_STRING} ^(.*)&(.*)$
RewriteRule ^(.*)$ /$1?%1&%2 [L,R=301]
# Запрет листинга директорий
Options -Indexes +ExecCGI
# Блокировка прямого доступа к чувствительным файлам
<FilesMatch "(?i)((config\.php|\.env|\.sql|\.bak|\.twig\.tpl|\.ini|\.log\.txt))">
Require all denied
</FilesMatch>
# === URL-перезапись (SEO) ===
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
# Пропуск статики — не обрабатывать через PHP
RewriteRule ^(.+\.(js|css|png|jpg|jpeg|gif|webp|ico|svg))$ - [L]
# Карта сайта
RewriteRule ^sitemap.xml$ index.php?route=feed/fast_sitemap [L]
RewriteRule ^sitemap([^\.]+).xml$ index.php?route=feed/fast_sitemap&path=$1 [L]
RewriteRule ^googlebase.xml$ index.php?route=extension/feed/google_base [L]
# Защита от доступа к системным файлам
RewriteRule ^system/download/(.*) index.php?route=error/not_found [L]
# Основное правило — все остальные запросы в index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
</IfModule>
# === HTTP-заголовки: безопасность и кэширование ===
<IfModule mod_headers.c>
# Безопасные заголовки
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1; mode=block"
Header set Referrer-Policy "no-referrer-when-downgrade"
Header set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
# manifest.json — правильный тип + без кэширования
<FilesMatch "^manifest\.json$">
Header set Content-Type "application/manifest+json"
Header unset Cache-Control
</FilesMatch>
# CORS для статики (если нужен)
<FilesMatch "\.(webp|png|jpg|jpeg|ico|js|css)$">
Header set Access-Control-Allow-Origin "https://example.com"
Header set Access-Control-Allow-Methods "GET, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type"
</FilesMatch>
# Неизменяемые JS-файлы (маршруты, трекеры и т.п.)
<FilesMatch "\.(js\.route|js\.track|js\.pref|js\.sfc|js\.asc)$">
Header set Content-Type "application/javascript"
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
# service-worker.js — не кэшировать!
<FilesMatch "^service-worker\.js$">
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "0"
</FilesMatch>
# Кэширование статики
<FilesMatch "\.(js|css)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
<FilesMatch "\.(webp|png|jpg|jpeg|gif|svg)$">
Header set Cache-Control "public, max-age=2592000"
</FilesMatch>
<FilesMatch "\.(woff2?|ttf|otf)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
<FilesMatch "\.json$">
Header set Cache-Control "public, max-age=86400"
</FilesMatch>
# Кэширование статических HTML-страниц
<FilesMatch "^(sitemap|privacy|about)\.html$">
Header set Cache-Control "public, max-age=60, stale-while-revalidate=60"
</FilesMatch>
# Поддержка сжатия: Vary по Accept-Encoding
Header append Vary Accept-Encoding
</IfModule>
# === Кэширование через Expires ===
<IfModule mod_expires.c>
ExpiresActive On
# Статика — 1 год
ExpiresByType text/css A31536000
ExpiresByType text/javascript A31536000
ExpiresByType application/javascript A31536000
ExpiresByType image/svg+xml A31536000
# Изображения — 1 месяц
ExpiresByType image/webp A2592000
ExpiresByType image/png A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/jpg A2592000
ExpiresByType image/gif A2592000
# Шрифты — 1 год
ExpiresByType font/woff A31536000
ExpiresByType font/woff2 A31536000
# JSON — 1 день
ExpiresByType application/json A86400
</IfModule>
# === MIME-типы ===
<IfModule mod_mime.c>
AddType text/xml xml
AddType application/javascript js
AddType application/vnd.ms-fontobject eot
AddType application/x-font-ttf ttf ttc
AddType font/opentype otf
AddType font/woff woff
AddType font/woff2 woff2
AddType image/svg+xml svg
AddType image/webp webp
</IfModule>
# === Сжатие: Brotli (приоритет) ===
<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css application/json application/javascript application/xml
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|svg|mp4|ogg|mp3|avi|flv|mov)(?:\?.*)?$ no-brotli
<FilesMatch "\.(css|js|html|php)$">
SetOutputFilter BROTLI_COMPRESS
</FilesMatch>
</IfModule>
# === Сжатие: Gzip (fallback) ===
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/css application/json application/javascript application/xml
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|svg|mp4|ogg|mp3|avi|flv|mov)(?:\?.*)?$ no-gzip dont-vary
<FilesMatch "\.(css|js|html|php)$">
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>
# === Дополнительные настройки ===
# Генерация ETag для эффективного кэширования
FileETag MTime Size
Файл: /etc/php71w/php-fpm.d/site.conf
[site]
; Сокет для Apache
listen = /var/run/php-fpm/php-site.sock
; Изоляция через chroot (опционально)
chroot = /path/to/site
chdir = /
; Разрешить подключение только с localhost
listen.allowed_clients = 127.0.0.1
; Корень сайта
php_admin_value[doc_root] = /public_html
php_admin_value[include_path] = .:/public_html
; Пользователь и группа
user = siteuser
group = sitegroup
; Настройки сокета
listen.owner = apache
listen.group = apache
listen.mode = 0666
; Максимальная очередь подключений (важно при всплесках)
listen.backlog = 4096
; Стратегия управления процессами
pm = dynamic
pm.max_children = 120
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
; Перезапуск после N запросов — профилактика утечек
pm.max_requests = 500
; Таймаут бездействия
pm.process_idle_timeout = 60s
; Лимиты ресурсов
rlimit_files = 50000
rlimit_core = unlimited
; Убить скрипт, если выполняется дольше 20 секунд
request_terminate_timeout = 20s
; Только PHP-файлы могут выполняться
security.limit_extensions = .php
; === Настройки OPcache (можно вынести в отдельный файл) ===
php_admin_value[opcache.enable] = 1
php_admin_value[opcache.memory_consumption] = 2048
php_admin_value[opcache.interned_strings_buffer] = 32
php_admin_value[opcache.max_accelerated_files] = 100000
php_admin_value[opcache.revalidate_freq] = 60
php_admin_value[opcache.fast_shutdown] = 1
php_admin_value[opcache.error_log] = /var/log/php-fpm/opcache.log
php_admin_value[opcache.log_verbosity_level] = 3
; Сессии
php_value[session.save_handler] = files
php_value[session.save_path] = /tmp
/etc/php.d/10-opcache.ini)zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=0
opcache.memory_consumption=2048
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=100000
opcache.use_cwd=1
opcache.validate_timestamps=0
opcache.revalidate_freq=60
opcache.save_comments=0
opcache.fast_shutdown=1
opcache.blacklist_filename=/etc/php.d/opcache*.blacklist
opcache.error_log=/var/log/php-fpm/opcache-error.log
opcache.log_verbosity_level=1
; Использует huge pages (2M вместо 4K) — снижает нагрузку на TLB
; Требует: echo 'vm.nr_hugepages = 1280' >> /etc/sysctl.conf && sysctl -p
opcache.huge_code_pages=1
opcache.file_update_protection=10
После настройки OPcache с параметрами:
opcache.memory_consumption=2048
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=100000
opcache.validate_timestamps=0
opcache.huge_code_pages=1
Рекомендуется регулярно проверять его состояние. Это позволяет:
Через функцию opcache_get_status() можно получить полную информацию о работе кэша.
Array
(
[opcache_enabled] => 1
[memory_usage] => Array
(
[used_memory] => 94356256 /* ~90 МБ */
[free_memory] => 2053127392 /* ~1.91 ГБ свободно */
[wasted_memory] => 0
[current_wasted_percentage] => 0
)
[interned_strings_usage] => Array
(
[buffer_size] => 33554432 /* 32 МБ */
[used_memory] => 2535032 /* ~2.4 МБ использовано */
[free_memory] => 31019400 /* ~29.6 МБ свободно */
[number_of_strings] => 41815
)
[opcache_statistics] => Array
(
[num_cached_scripts] => 698 /* Файлов в кэше */
[hits] => 13521943 /* Успешных обращений */
[misses] => 804 /* Промахов */
[opcache_hit_rate] => 99.994 /* Хитрейт: почти идеал */
[oom_restarts] => 0 /* Перезапусков из-за нехватки памяти */
[hash_restarts] => 0 /* Коллизий хешей */
[manual_restarts] => 0 /* Ручных сбросов */
[start_time] => 1771470603 /* Время запуска (Unix) */
)
[scripts] => Array /* Детали по файлам */
(
[/sites/.../zemez_search.php] => Array
(
[hits] => 54809 /* Часто используется (поиск) */
[memory_consumption] => 1936
)
[/sites/storage/cache/.../02accountlogin.inc] => Array
(
[hits] => 55
[memory_consumption] => 48672 /* Большой файл (~48 КБ) */
)
[/sites/.../RawHeadersParser.php] => Array
(
[hits] => 2 /* Редко используется */
)
)
)
| Метрика | Значение | Что значит | Рекомендация |
|---|---|---|---|
opcache_hit_rate |
99.994% | Почти все запросы обслуживаются из кэша | Идеально. PHP не компилируется повторно |
misses |
804 | Мало промахов при 13.5 млн обращений | max_accelerated_files достаточно |
oom_restarts |
0 | Не было исчерпания памяти | memory_consumption=2048 подобран верно |
interned_strings_usage |
~2.4 МБ из 32 МБ | Буфер строк почти не используется | Можно уменьшить до 16 МБ |
num_cached_scripts |
698 | Из 100K возможных — используется мало | Норма для OpenCart / WordPress |
scripts[hits] |
от 2 до 54809 | Видно, какие файлы "горячие" | Полезно для профилирования |
Создайте скрипт для сбора данных: /var/www/monitoring/opcache-metrics.php
<?php
// Запрет доступа снаружи
if ($_SERVER['REMOTE_ADDR'] !== '127.0.0.1' && $_SERVER['REMOTE_ADDR'] !== '::1') {
http_response_code(403);
exit('Access denied');
}
// Только GET
if ($_SERVER['REQUEST_METHOD'] !== 'GET') {
http_response_code(405);
exit('Method not allowed');
}
$status = opcache_get_status(false);
if (!$status || !isset($status['opcache_statistics'])) {
http_response_code(500);
exit('OPcache not available or disabled');
}
$stats = $status['opcache_statistics'];
$memory = $status['memory_usage'];
$strings = $status['interned_strings_usage'];
function mb($bytes) {
return round($bytes / (1024 * 1024), 2);
}
header('Content-Type: text/plain; charset=UTF-8');
echo "# HELP opcache_enabled OPcache включён\n";
echo "# TYPE opcache_enabled gauge\n";
echo "opcache_enabled 1\n\n";
echo "# HELP opcache_hit_rate Процент попаданий в кэш\n";
echo "# TYPE opcache_hit_rate gauge\n";
echo "opcache_hit_rate " . number_format($stats['opcache_hit_rate'], 6) . "\n\n";
echo "# HELP opcache_memory_usage_bytes Использование памяти OPcache\n";
echo "# TYPE opcache_memory_usage_bytes gauge\n";
echo "opcache_memory_usage_bytes{type=\"used\"} {$memory['used_memory']}\n";
echo "opcache_memory_usage_bytes{type=\"free\"} {$memory['free_memory']}\n";
echo "opcache_memory_usage_bytes{type=\"wasted\"} {$memory['wasted_memory']}\n\n";
echo "# HELP opcache_interned_strings_usage_bytes Использование буфера строк\n";
echo "# TYPE opcache_interned_strings_usage_bytes gauge\n";
echo "opcache_interned_strings_usage_bytes{type=\"used\"} {$strings['used_memory']}\n";
echo "opcache_interned_strings_usage_bytes{type=\"free\"} {$strings['free_memory']}\n\n";
echo "# HELP opcache_cache_stats Статистика кэша\n";
echo "# TYPE opcache_cache_stats counter\n";
echo "opcache_cache_stats{event=\"hits\"} {$stats['hits']}\n";
echo "opcache_cache_stats{event=\"misses\"} {$stats['misses']}\n";
echo "opcache_cache_stats{event=\"oom_restarts\"} {$stats['oom_restarts']}\n";
echo "opcache_cache_stats{event=\"hash_restarts\"} {$stats['hash_restarts']}\n";
echo "opcache_cache_stats{event=\"manual_restarts\"} {$stats['manual_restarts']}\n\n";
echo "# HELP opcache_script_count Количество закешированных скриптов\n";
echo "# TYPE opcache_script_count gauge\n";
echo "opcache_script_count {$stats['num_cached_scripts']}\n\n";
echo "# HELP opcache_uptime_seconds Время работы OPcache\n";
echo "# TYPE opcache_uptime_seconds gauge\n";
echo "opcache_uptime_seconds " . (time() - $stats['start_time']) . "\n\n";
Разрешите доступ только с localhost.
Apache (.htaccess или vhost):
<Location "/monitoring/opcache-metrics.php">
Require local
</Location>
Nginx (в конфигурацию сайта):
location = /monitoring/opcache-metrics.php {
allow 127.0.0.1;
deny all;
fastcgi_pass unix:/var/run/php-fpm/www.sock;
include fastcgi_params;
}
Добавьте задачу в prometheus.yml:
scrape_configs:
- job_name: 'opcache'
scrape_interval: 30s
static_configs:
- targets: ['127.0.0.1:80']
metrics_path: /monitoring/opcache-metrics.php
relabel_configs:
- source_labels: [__address__]
target_label: instance
replacement: 'php-fpm-opcache'
Импортируйте следующий JSON в Grafana: Dashboard → Import → Paste JSON
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": null,
"links": [],
"panels": [
{
"datasource": "Prometheus",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "orange",
"value": 95
},
{
"color": "red",
"value": 98
}
]
},
"unit": "percent"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 8,
"x": 0,
"y": 0
},
"id": 1,
"options": {
"orientation": "horizontal",
"reduceOptions": {
"calcs": [
"last"
],
"fields": "",
"values": false
},
"showThresholdLabels": false,
"showUnfilled": true,
"text": {}
},
"pluginVersion": "8.3.3",
"targets": [
{
"expr": "opcache_hit_rate",
"interval": "",
"legendFormat": "Hit Rate",
"refId": "A"
}
],
"title": "OPcache Hit Rate",
"type": "gauge"
},
{
"datasource": "Prometheus",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 20,
"gradientMode": "opacity",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 2,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
}
]
},
"unit": "decbytes"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 16,
"x": 8,
"y": 0
},
"id": 2,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "multi",
"sort": "none"
}
},
"targets": [
{
"expr": "opcache_memory_usage_bytes",
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
}
],
"title": "Memory Usage",
"type": "timeseries"
},
{
"datasource": "Prometheus",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 1
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 6,
"x": 0,
"y": 6
},
"id": 3,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"last"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"pluginVersion": "8.3.3",
"targets": [
{
"expr": "opcache_cache_stats{event=\"oom_restarts\"}",
"interval": "",
"legendFormat": "OOM Restarts",
"refId": "A"
}
],
"title": "OOM Restarts",
"type": "stat"
},
{
"datasource": "Prometheus",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 1
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 6,
"x": 6,
"y": 6
},
"id": 4,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"last"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"targets": [
{
"expr": "opcache_cache_stats{event=\"hash_restarts\"}",
"interval": "",
"legendFormat": "Hash Restarts",
"refId": "A"
}
],
"title": "Hash Restarts",
"type": "stat"
},
{
"datasource": "Prometheus",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 1
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 4,
"w": 6,
"x": 12,
"y": 6
},
"id": 5,
"options": {
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"orientation": "auto",
"reduceOptions": {
"calcs": [
"last"
],
"fields": "",
"values": false
},
"textMode": "auto"
},
"targets": [
{
"expr": "opcache_script_count",
"interval": "",
"legendFormat": "Cached Scripts",
"refId": "A"
}
],
"title": "Cached Scripts",
"type": "stat"
},
{
"datasource": "Prometheus",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "bars",
"fillOpacity": 100,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineWidth": 0,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
}
]
},
"unit": "s"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 10
},
"id": 6,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "single"
}
},
"targets": [
{
"expr": "opcache_uptime_seconds",
"interval": "",
"legendFormat": "Uptime",
"refId": "A"
}
],
"title": "OPcache Uptime",
"type": "bargauge"
},
{
"datasource": "Prometheus",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 20,
"gradientMode": "opacity",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "smooth",
"lineWidth": 2,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green"
}
]
},
"unit": "none"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 10
},
"id": 7,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom"
},
"tooltip": {
"mode": "multi",
"sort": "desc"
}
},
"targets": [
{
"expr": "rate(opcache_cache_stats{event=\"hits\"}[5m])",
"interval": "",
"legendFormat": "Hits/sec",
"refId": "A"
},
{
"expr": "rate(opcache_cache_stats{event=\"misses\"}[5m])",
"interval": "",
"legendFormat": "Misses/sec",
"refId": "B"
}
],
"title": "Hit/Miss Rate (5m)",
"type": "timeseries"
}
],
"refresh": "30s",
"schemaVersion": 36,
"style": "dark",
"tags": [
"php",
"opcache",
"performance"
],
"templating": {
"list": []
},
"time": {
"from": "now-1h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "PHP OPcache Monitoring",
"uid": "opcache-dashboard",
"version": 1
}
Важно: opcache.validate_timestamps=0 отключает проверку изменений файлов.
Обновление кэша — только через перезапуск PHP-FPM или вызов opcache_reset().
Для production — идеально. Для разработки — временно отключить.
Такой подход превращает OPcache из «чёрного ящика» в прозрачный, контролируемый компонент архитектуры.
Memcached и Redis кэшируют данные, но не готовые HTML-страницы. Для максимальной скорости — кэшируйте целые страницы до запуска контроллеров.
Решение: использовать APCu (встроен в PHP) для хранения HTML с учётом:
Ключевые особенности:
Пример (упрощённо):
<?php
$key = 'page_' . md5($_SERVER['REQUEST_URI'] . $_SERVER['HTTP_USER_AGENT']);
$html = apcu_fetch($key);
if ($html !== false) {
echo gzdecode($html);
exit;
}
// ... выполнение контроллера ...
apcu_store($key, gzencode($output), 3600); // 1 час
Brotli применяется только к статике (JS, CSS, JSON), так как выигрыш в сжатии оправдан. Для динамических HTML — GZIP на уровне кэширования эффективнее.
Запускается по cron. Прогревает ключевые страницы для ПК и мобильных.
#!/bin/bash
# Скрипт: /path/to/scripts/preload_pages.sh
# Запуск: */15 * * * * /path/to/scripts/preload_pages.sh
SCRIPT_NAME=$(basename "$0")
START_TIME=$(date +%s)
PAGES_FILE="/path/to/scripts/txt/pages_to_warm.txt"
echo "🚀 Запущен скрипт $SCRIPT_NAME в $(date)"
if [ ! -f "$PAGES_FILE" ]; then
echo "❌ Файл $PAGES_FILE не найден"
exit 1
fi
if [ ! -s "$PAGES_FILE" ]; then
echo "❌ Файл $PAGES_FILE пустой"
exit 1
fi
readarray -t UNIQUE_PAGES < "$PAGES_FILE"
DESKTOP_PAGES=0
MOBILE_PAGES=0
echo "🔥 Начинаем прогрев страниц для ПК..."
for PAGE in "${UNIQUE_PAGES[@]}"; do
URL="https://example.com$PAGE"
HTTP_CODE=$(curl -fs -o /dev/null -w "%{http_code}" --connect-timeout 10 "$URL")
if [ "$HTTP_CODE" -eq 200 ]; then
((DESKTOP_PAGES++))
else
echo "⚠️ Ошибка прогрева ($HTTP_CODE): $URL"
fi
sleep 0.5
done
echo "✅ Прогреты $DESKTOP_PAGES страниц для ПК"
echo "📱 Начинаем прогрев страниц для смартфонов..."
for PAGE in "${UNIQUE_PAGES[@]}"; do
URL="https://example.com$PAGE"
HTTP_CODE=$(curl -fs -o /dev/null -w "%{http_code}" \
--connect-timeout 10 \
-A "Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1" \
"$URL")
if [ "$HTTP_CODE" -eq 200 ]; then
((MOBILE_PAGES++))
else
echo "⚠️ Ошибка прогрева ($HTTP_CODE): $URL"
fi
sleep 0.5
done
echo "✅ Прогреты $MOBILE_PAGES страниц для смартфонов"
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
echo "🎉 Общая статистика:"
echo " ⚙️ ПК: $DESKTOP_PAGES страниц"
echo " 📱 Смартфоны: $MOBILE_PAGES страниц"
echo "⏳ Общее время выполнения: $DURATION секунд"
/path/to/scripts/txt/pages_to_warm.txt/
/category/popular
/product/featured-1
/product/featured-2
/information/delivery
/information/privacy
/blog/news-1
/blog/news-2
Разделите страницы на группы и запустите несколько скриптов с разной периодичностью (например, каждые 15, 30, 60 минут), если контент сильно варьируется.
Чтобы сделать переходы ещё быстрее:
Пример предзагрузки при наведении:
document.addEventListener('mouseover', (e) => {
const link = e.target.closest('a');
if (link && shouldPreload(link.href)) {
fetch(link.href, { method: 'HEAD' });
}
});
Результат — переходы как в нативном приложении.
После настройки сервера необходимо обязательно диагностировать состояние системы, просматривать логи, тестировать нагрузку и управлять сервисами. Ниже — набор примеров практических команд для администрирования.
# Проверка состояния ключевых служб
sudo systemctl status mysqld
sudo systemctl status httpd
sudo systemctl status nginx
sudo systemctl status php-fpm
sudo systemctl status php71w-fpm@appname.service # если используется pool
# Состояние планировщика задач
systemctl status cron || systemctl status crond || systemctl status systemd-timer
systemctl statusMySQL (высокая нагрузка, кэширование в RAM)
● mysqld.service - MySQL database server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled)
Active: active (running) since Mon 2026-01-01 01:00:14 +03; 1 months 22 days ago
Main PID: 27104 (mysqld_safe)
Tasks: 61
Memory: 5.4G
CGroup: /system.slice/mysqld.service
├─27104 /bin/sh /usr/bin/mysqld_safe --basedir=/usr
└─27769 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --log-error=server.err --open-files-limit=10000
Warning: Journal has been rotated since unit was started. Log output is incomplete.
PHP-FPM (pool с высокой активностью)
● php71w-fpm@site.service - The PHP FastCGI Process Manager - site
Loaded: loaded (/usr/lib/systemd/system/php71w-fpm@site.service; enabled)
Active: active (running) since Thu 2026-02-19 08:10:03 +03; 3 days ago
Main PID: 7319 (php-fpm)
Status: "Processes active: 0, idle: 26, Requests: 148825, slow: 0, Traffic: 0.3req/sec"
Tasks: 27
Memory: 508.6M
CGroup: /system.slice/system-php71w\x2dfpm.slice/php71w-fpm@site.service
├─ 7319 php-fpm: master process (/etc/php71w/php-fpm.site.conf)
├─ 7427 php-fpm: pool site
├─18313 php-fpm: pool site
...
└─32641 php-fpm: pool site
Apache (обслуживает CMS, высокая нагрузка, graceful reloads)
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled)
Active: active (running) since Mon 2026-01-01 01:00:16 +03; 1 months 22 days ago
Docs: man:httpd.service(8)
Process: 21699 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited, status=0/SUCCESS)
Main PID: 27819 (httpd)
Status: "Total requests: 1528011; Idle/Busy workers 98/1; Requests/sec: 0.337; Bytes/sec: 19KB"
Tasks: 213
Memory: 530.6M
CGroup: /system.slice/httpd.service
├─21712 /usr/sbin/httpd -DFOREGROUND
├─21757 /usr/sbin/httpd -DFOREGROUND
...
└─27819 /usr/sbin/httpd -DFOREGROUND
Feb 22 12:00:03 server systemd[1]: Reloaded The Apache HTTP Server.
Nginx (обслуживает MySQL, phpMyAdmin, BrainyCP, Roundcube, Squirrelmail, API)
● nginxb.service - The Nginx HTTP Server
Loaded: loaded (/usr/lib/systemd/system/nginxb.service; enabled)
Active: active (running) since Mon 2026-01-01 01:00:17 +03; 1 months 22 days ago
Process: 28287 ExecStart=/usr/sbin/nginxb (code=exited, status=0/SUCCESS)
Main PID: 28288 (nginxb)
Tasks: 8
Memory: 44.3M
CGroup: /system.slice/nginxb.service
├─28288 nginx: master process /usr/sbin/nginxb
├─28289 nginx: worker process
...
└─28295 nginx: cache manager process
Cron — планировщик задач
● crond.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled)
Active: active (running) since Sat 2025-10-04 21:09:14 +03; 4 months 18 days ago
Main PID: 571 (crond)
Tasks: 1
Memory: 2.3M
CGroup: /system.slice/crond.service
└─571 /usr/sbin/crond -n
# Apache Benchmark: 1000 запросов, 100 параллельных соединений
ab -n 1000 -c 100 https://example.com/
# Краткий HTTP-тест (проверка времени ответа)
curl -o /dev/null -s -w "DNS: %{time_namelookup} | Connect: %{time_connect} | TTFB: %{time_starttransfer} | Total: %{time_total}\n" https://example.com/
# Загрузка CPU, памяти, процессов
htop
# Дисковый I/O (в реальном времени)
iotop
# Объём свободной памяти
free -h
# Поиск запущенных процессов
pgrep mysqld
pgrep httpd
pgrep nginx
pgrep php-fpm
# Все процессы (с фильтром по ключевым службам)
ps aux | grep -E 'mysqld|httpd|nginx|php-fpm'
# Топ-10 процессов по потреблению памяти
ps aux --sort=-%mem | head -n 10
# Статистика загрузки CPU (5 измерений с интервалом 1 сек)
mpstat 1 5
# Общий объём использования диска
df -h
# Размер корневых директорий (отсортировано по убыванию)
sudo du -sh /* 2>/dev/null | grep -v '^0\.' | sort -hr
# Размер поддиректорий /var
du -sh /var/* 2>/dev/null | sort -hr
# Поиск файлов больше 100 МБ
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | head -20
# MySQL
sudo tail -f /var/log/mysqld.log
sudo tail -n 20 -f /var/log/mysqld.log
tail -n 20 /var/lib/mysql/example.com.err
# Apache
sudo tail -f /var/log/httpd/error_log
sudo tail -n 20 -f /var/log/httpd/error_log
sudo tail -n 50 /etc/httpd/vhost_logs/example.com_error
# Nginx
tail -f /var/log/nginx/error.log
sudo tail -n 20 -f /var/log/nginx/error.log
# PHP-FPM
tail -f /var/log/php-fpm/appname.log
sudo tail -n 20 -f /var/log/php-fpm/appname.log
# OPcache
sudo tail -f /var/log/php-fpm/opcache.log
sudo tail -n 20 -f /var/log/php-fpm/opcache.log
# Cron
cat /var/log/cron | grep -i "preload\|php"
# Проверка активных модулей Apache
grep -r 'LoadModule' /etc/httpd/conf.modules.d/
# Проверка синтаксиса Apache
sudo apachectl configtest
# Проверка синтаксиса Nginx
/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
# Проверка подключённых виртуальных хостов
apache2ctl -S || httpd -S
nginx -T 2>/dev/null | grep server_name
# Перезапуск MySQL
sudo systemctl restart mysqld
# Перезапуск веб-серверов
sudo systemctl restart httpd
sudo systemctl restart nginx
# Перезапуск PHP-FPM
sudo systemctl restart php-fpm
sudo systemctl restart php71w-fpm@appname.service
# Безопасная перезагрузка (не убивает соединения)
sudo systemctl reload httpd
sudo systemctl reload nginx
# Принудительная перезагрузка демона
sudo systemctl daemon-reexec
# Очистка OPcache
php -r 'opcache_reset();'
# Очистка APCu (если используется)
php -r 'apcu_clear_cache();'
# Очистка кеша приложения (пример для OpenCart, Laravel и др.)
rm -rf /path/to/site/storage/cache/*
rm -rf /path/to/site/system/storage/cache/*
# Проверка HTTP-статуса сайта
curl -I https://example.com/
# Подробная проверка с заголовками
curl -s -D - -o /dev/null -H "Host: example.com" http://127.0.0.1/
# Активные порты (80, 443 и др.)
sudo netstat -tuln | grep ':80\|:443'
sudo lsof -i :80
sudo lsof -i :443
# Проверка OCSP Stapling (SSL-кэш)
openssl s_client -connect example.com:443 -status -servername example.com 2>/dev/null | grep -A 10 -B 2 "OCSP response"
# Проверка сертификата
openssl x509 -in /path/to/ssl/example.com.crt -text -noout | grep -i "not after"
Команды htop, df -h, tail -f — отличны для разовой диагностики, но они:
Чтобы перейти к проактивному мониторингу, рекомендуется использовать стек Prometheus + Grafana + Node Exporter.
Node Exporter собирает метрики системы: CPU, память, диски, сеть.
# Скачайте и запустите Node Exporter
wget https://github.com/prometheus/node_exporter/releases/latest/download/node_exporter-*.linux-amd64.tar.gz
tar xvfz node_exporter-*.linux-amd64.tar.gz
cd node_exporter-*linux-amd64
# Запуск в фоне
./node_exporter &
# Проверка: http://your-server:9100/metrics
curl -s http://localhost:9100/metrics | head -10
Рекомендуется запускать через systemd для автозагрузки.
Добавьте задачу в prometheus.yml:
scrape_configs:
# ... другие job'ы ...
- job_name: 'node'
scrape_interval: 30s
static_configs:
- targets: ['your-server-ip:9100']
labels:
instance: 'production-web-01'
| Метрика | Аналог в SSH | Назначение |
|---|---|---|
node_cpu_seconds_total{mode="idle"} |
mpstat, htop |
Загрузка CPU в реальном времени |
node_memory_MemAvailable_bytes |
free -h |
Свободная память (точнее, чем MemFree) |
node_filesystem_avail_bytes |
df -h |
Свободное место на диске |
node_disk_io_time_seconds_total |
iotop |
Нагрузка на диск (I/O wait) |
node_network_receive_bytes_total |
iftop, ip -s link |
Трафик сети |
Импортируйте официальный дашборд: Node Exporter Full (ID: 1860)
Или используйте этот JSON-фрагмент (упрощённая версия):
{
"title": "Server Health",
"tags": ["node", "system", "production"],
"panels": [
{
"title": "CPU Usage",
"type": "timeseries",
"datasource": "Prometheus",
"targets": [
{
"expr": "100 - (avg by(instance) (rate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100)",
"legendFormat": "CPU Used %"
}
],
"unit": "percent"
},
{
"title": "Memory Usage",
"type": "timeseries",
"datasource": "Prometheus",
"targets": [
{
"expr": "(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100",
"legendFormat": "Used %"
}
],
"unit": "percent"
},
{
"title": "Disk Space (Root)",
"type": "gauge",
"datasource": "Prometheus",
"targets": [
{
"expr": "100 - ((node_filesystem_avail_bytes{mountpoint=\"/\"} / node_filesystem_size_bytes{mountpoint=\"/\"}) * 100)",
"legendFormat": "Used %"
}
],
"unit": "percent"
}
],
"refresh": "30s",
"schemaVersion": 36,
"version": 1
}
Пример: Вместо htop вы видите график CPU в Grafana за 24 часа и получаете алерт,
если нагрузка >90% более 5 минут.
Вместо df -h — дашборд с цветовыми индикаторами свободного места.
Вместо tail -f /var/log/php-fpm/appname.log — алерт при появлении PHP Fatal error через
Loki + Promtail.
tail -f в браузере)
Такой подход превращает реактивное администрирование (по SSH) в проактивный SRE-подход.
Комплексный подход к оптимизации стека LAMP/LEMP позволяет не только ускорить веб-сервис, но и сделать его стабильным, предсказуемым и легко управляемым под высокой нагрузкой.
Корректная настройка позволяет:
systemctl status, htop,
ab, логи и apachectl configtestПредставленные в документе настройки универсальны и применимы к любому PHP-приложению: OpenCart, WordPress, Laravel, Magento, Symfony и самописным CMS.
Рекомендация: минимизируйте реактивное администрирование. Настройте мониторинг: Prometheus + Grafana, алерты — это позволит выявлять проблемы до пользователей. Технический долг в инфраструктуре всегда приводит к росту TTFB, простою, снижению финансовых показателей, ущербу репутации компании и утрате доверия пользователей — целесообразнее его предотвратить, чем устранять последствия.
⇪
Документы