Моніторинг споживання оперативної пам'яті 1С-Бітрікс
PHP — процесова модель: кожен запит запускає новий PHP-FPM воркер, і кожен воркер споживає RAM незалежно. При pm.max_children = 50 та 64 МБ на воркер — це вже 3,2 ГБ тільки під PHP. На практиці Бітрікс-запити з важкими компонентами (імпорт з 1С, формування прайс-листів, складні звіти) споживають 128–256 МБ. Якщо сервер починає використовувати своп, час відповіді деградує в рази.
Що споживає пам'ять у Бітрікс
Головні джерела зростання RSS воркерів:
-
Імпорт з 1С через CommerceML —
CCatalogImportзавантажує XML повністю в пам'ять. При файлах > 50 МБ воркер легко набирає 200–300 МБ. -
Операції з інфоблоком —
CIBlockElement::GetList()безnTopCountповертає весь результат одразу. -
Кеш у пам'яті — якщо ввімкнено
managed_cache(memcached), локальна копія даних у PHP-процесі дублює кеш. -
Витоки у сторонніх модулях — статичні властивості, глобальні масиви, що накопичуються за час життя воркера при
pm.max_requests = 0.
Інструменти моніторингу
Системний рівень — кожні кілька секунд:
# Сумарна пам'ять по PHP-FPM процесах
ps aux --sort=-%mem | grep php-fpm | awk '{sum += $6} END {print sum/1024 " MB"}'
# Детально по кожному воркеру
ps aux | grep php-fpm | grep -v grep | awk '{print $6/1024 " MB\t" $11}'
PHP memory_limit — діагностика в коді:
// Показує пік споживання за час життя запиту
$peak = memory_get_peak_usage(true);
if ($peak > 64 * 1024 * 1024) { // > 64 МБ
\Bitrix\Main\Diag\Debug::writeToFile(
sprintf('Peak memory: %.1f MB, URI: %s', $peak / 1048576, $_SERVER['REQUEST_URI']),
'MEM_HIGH',
'/local/logs/memory.log'
);
}
Цей код додаємо в OnEndBufferContent — так покриваємо всі запити без інструментальних накладних витрат.
Prometheus + node_exporter + Grafana:
# prometheus.yml scrape config
- job_name: node
static_configs:
- targets: ['localhost:9100']
Метрика node_memory_MemAvailable_bytes — вільна пам'ять. Алерт при падінні нижче 512 МБ:
# alertmanager rule
- alert: LowMemory
expr: node_memory_MemAvailable_bytes < 536870912
for: 5m
annotations:
summary: "Low RAM on {{ $labels.instance }}"
PHP-FPM: параметри під контроль
Ключові параметри у /etc/php/8.1/fpm/pool.d/bitrix.conf:
pm = dynamic
pm.max_children = 30 ; не більше (RAM - 1GB) / avg_worker_memory
pm.max_requests = 500 ; перезапускаємо воркер після 500 запитів (захист від витоків)
pm.process_idle_timeout = 30s
; Статус-сторінка для моніторингу
pm.status_path = /php-fpm-status
pm.max_requests = 500 — воркер перезапускається після 500 запитів, скидаючи будь-які витоки пам'яті. При нормальному коді це непотрібно, але сторонні модулі Бітрікс іноді накопичують статику.
Кейс: сайт з щоденним імпортом
Інтернет-магазин, імпорт з 1С о 02:00 через cron_events. Після імпорту кілька PHP-FPM воркерів залишалися з RSS 250–300 МБ, сервер (8 ГБ) йшов у своп, і вранці до 07:00 сайт гальмував.
Діагностика: max_requests був 0, роздуті воркери не перезапускалися. pm.max_requests = 200 та обмеження memory_limit = 256M (було 512M) вирішили проблему: роздуті воркери вмирали після 200 запитів, пам'ять поверталася системі.







