Ошибка systemd: CPUQuota exceeded — Троттлинг процессов в cgroups
Сервис начинает работать с огромными задержками (latency spikes), время отклика API возрастает в десятки раз, но общая загрузка процессора хоста остается низкой. В метриках фиксируется троттлинг: CPUQuota exceeded: Throttling service CPU utilization.
| Метрика / Файл | Значение | Следствие |
|---|---|---|
CPUQuota=100% | Эквивалент 1 процессорного ядра | Многопоточное приложение мгновенно исчерпывает квоту |
cpu.stat (nr_throttled) | Рост счетчика блокировок | Ядро Linux принудительно усыпляет потоки приложения |
| Задержка обработки очередей | Резкий рост p99 latency | Приложение «замирает» до наступления следующего периода CFS |
- Приложение не падает, но «подвисает» на доли секунды внутри каждого 100ms интервала CFS.
- Мониторинг показывает высокое время отклика сервиса при загрузке CPU внутри cgroup на уровне 100%.
- Проверьте статистику троттлинга процессора для конкретного юнита:
cat /sys/fs/cgroup/system.slice/<service_name>.service/cpu.stat # Обратите внимание на параметры nr_throttled и throttled_usec - Проверьте текущую конфигурацию квоты процессора в юните:
systemctl show <service_name> -p CPUQuota -p CPUWeight - Увеличьте лимит
CPUQuota. Учитывайте, что 100% = 1 полное ядро CPU, 400% = 4 ядра:sudo systemctl edit <service_name>.service # Задайте пропорциональную квоту: [Service] CPUQuota=400% # Либо назначьте приоритет вместо жесткого ограничения: CPUWeight=200 - Если требуется распределение процессорных ядер, привяжите сервис к конкретным ядрам через
CPUAffinity:[Service] CPUAffinity=0 1 2 3 - Примените конфигурацию без прерывания работы сервиса:
sudo systemctl daemon-reload sudo systemctl set-property <service_name> CPUQuota=400%
CPUQuota (CFS Quota) в многопоточных микросервисах (Java, Go) часто вызывают паразитный троттлинг из-за всплесков фоновых потоков сборки мусора (GC). Предпочитайте использование CPUWeight (shares) жестким квотам.Частые вопросы (FAQ)
Как рассчитывается процент CPUQuota в systemd?
100% означает гарантированное время одного логического ядра CPU за базовый период CFS (обычно 100 мс). Для 8-ядерного сервера максимальное теоретическое значение CPUQuota составляет 800%.
Чем отличается CPUQuota от CPUWeight?
CPUQuota задает жесткий потолок времени выполнения вне зависимости от доступности ресурсов. CPUWeight определяет относительный вес приоритета сервиса при конкуренции за процессор, позволяя утилизировать 100% свободных ресурсов, когда другие сервисы простаивают.
Как динамически изменить CPUQuota работающего сервиса без рестарта?
Выполните команду: sudo systemctl set-property <service_name> CPUQuota=200%.
Где посмотреть количество троттлинга в cgroups v1?
В файле /sys/fs/cgroup/cpu/system.slice/<unit>/cpu.stat (строки nr_periods и nr_throttled).