> Какой план действий при перегрузке CPU и срабатывании алерта (Go)
Уровень: middle · Роль: backend · Категория: Технические вопросы
Компании: Wildberries
Стек: Go
> Пример ответа
Короткий ответ
План действий при перегрузке CPU: сначала зафиксировать алерт и оценить критичность, затем посмотреть дашборды (CPU, load average, goroutines, GC, latency), определить, это рост трафика или деградация кода, после чего - профилировать приложение (pprof), проверить логи и деплои, при необходимости - откатить релиз или масштабироваться. Параллельно смотреть на инфраструктуру: не упираемся ли в лимиты ноды, нет ли проблем с соседями. Главное - действовать по приоритету: сначала восстановить сервис, потом разбираться в причинах.
Подробное объяснение
Перегрузка CPU в Go-сервисе - это сигнал, что либо нагрузка выросла, либо код стал неэффективным. План действий строится по принципу "сначала стабилизация, потом диагностика".
-
Зафиксировать алерт и оценить severity. Если SLO горит (latency растёт, ошибки появляются) - это инцидент, действуем быстро. Если CPU высокий, но latency в норме - можно спокойно разбираться.
-
Посмотреть метрики. Ключевые: CPU usage, load average, количество goroutines, частота GC, heap size, latency percentiles, RPS. Сравнить с базовой линией (baseline) за последние сутки/неделю.
-
Определить тип перегрузки:
- Рост трафика - RPS вырос, CPU растёт пропорционально. Тогда вопрос: это ожидаемо? Если да - масштабирование, если нет - ищем аномалию (боты, ретраи, неправильный клиент).
- Деградация кода - RPS тот же, а CPU вырос. Тогда ищем проблему в коде: утечка goroutines, бесконечный цикл, деградация алгоритма, проблема с GC (например, слишком много аллокаций).
- Инфраструктура - проблема на ноде: соседи по хосту, проблемы с диском/сетью, которые вызывают ретраи и рост CPU.
-
Профилирование. Если деградация кода - снимаем CPU profile через pprof (runtime/pprof или net/http/pprof). Смотрим топ функций по CPU time. Обращаем внимание на:
runtime.mallocgc- много аллокаций, проблема с памятью.runtime.futex- блокировки, contention.syscall- много системных вызовов.- конкретные функции бизнес-логики.
-
Проверить деплой. Если CPU вырос после релиза - почти наверняка проблема в новом коде. Откат - самый быстрый способ восстановить сервис.
-
Принять меры:
- Откатить релиз.
- Масштабировать (добавить подов/нод).
- Включить rate limiting или circuit breaker на входе.
- Ограничить concurrency внутри сервиса (semaphore).
- Перезапустить поды (временная мера, если утечка goroutines).
-
После стабилизации - разбор: смотрим логи, трейсы, профиль, пишем постмортем.
На практике
Типичный сценарий для Go-бэкенда: алерт "CPU > 80%" на поде. Первое действие - открыть Grafana и посмотреть панель с RPS и latency. Если RPS вырос в 3 раза - это нагрузка, скорее всего, от клиента или бота. Если RPS тот же, а CPU вырос - смотрим на pprof.
Практический порядок действий:
- Открыть дашборд, оценить тренд за 15-30 минут.
- Проверить, был ли деплой за последний час.
- Если деплой был - откатить.
- Если нет - подключиться к поду и снять профиль:
go tool pprof http://pod:8080/debug/pprof/profile?seconds=30 - Посмотреть топ функций. Если видим
runtime.gc- проблема с аллокациями, смотрим heap profile. - Если видим свою функцию - смотрим код, ищем неэффективность.
- Если ничего не видно - снимаем трассировку (trace) и смотрим, где goroutines блокируются.
Важно: не пытаться "лечить" симптомами (просто рестартовать поды), если это не критично. Но если SLO горит - рестарт допустим как временная мера.
Пример кода
Пример снятия CPU profile в production (аккуратно, только если включён pprof):
GO// main.go - включаем pprof на отдельном портуimport ("net/http"_ "net/http/pprof")func main() {// отдельный сервер для pprof, не на основном портуgo func() {http.ListenAndServe(":6060", nil)}()// ... основной код}
Снятие профиля и анализ:
BASH# снять CPU profile за 30 секундcurl -o cpu.prof http://localhost:6060/debug/pprof/profile?seconds=30# посмотреть топ функцийgo tool pprof -top cpu.prof# интерактивный режимgo tool pprof cpu.prof
Пример вывода top:
Showing nodes accounting for 12.34s, 85.2% of 14.48s total flat flat% sum% cum cum% 4.12s 28.5% 28.5% 4.12s 28.5% runtime.memmove 3.20s 22.1% 50.6% 3.20s 22.1% encoding/json.(*Decoder).refill 2.10s 14.5% 65.1% 2.10s 14.5% runtime.mallocgc
Если видим runtime.memmove и encoding/json - скорее всего, проблема в парсинге больших JSON. Тогда смотрим heap profile:
BASHcurl -o heap.prof http://localhost:6060/debug/pprof/heapgo tool pprof -top heap.prof
Как отвечать на собеседовании
Начните с того, что сначала оцениваете критичность: если SLO горит - действуете быстро, если нет - спокойно диагностируете. Затем опишите порядок: метрики → деплой → профилирование → меры. Подчеркните, что в Go ключевой инструмент - pprof, и что вы умеете читать его вывод. Упомяните, что важно отличать рост трафика от деградации кода. Если спросят про конкретные шаги - назовите откат релиза, масштабирование, rate limiting. Покажите, что понимаете trade-off между скоростью восстановления и глубиной диагностики: иногда рестарт - это нормально, если сервис лежит.
Что проверяет интервьюер
Интервьюер проверяет:
- Системное мышление - умеете ли вы действовать по приоритетам, а не хаотично.
- Знание инструментов - pprof, метрики, дашборды.
- Понимание Go-специфики - goroutines, GC, аллокации, contention.
- Умение отличать симптомы от причин - не предлагаете ли вы рестарт как единственное решение.
- Опыт инцидентов - говорите ли вы о реальных сценариях (деплой, трафик, инфраструктура).
Типичные ошибки
- Сразу рестартовать без оценки - теряете диагностическую информацию, проблема вернётся.
- Смотреть только CPU - игнорируете latency, RPS, ошибки, которые важнее.
- Не проверять деплой - самая частая причина, а вы лезете в профилирование.
- Снимать профиль в production без осторожности - pprof сам по себе нагружает CPU, на пике это может усугубить.
- Путать рост трафика и деградацию кода - если RPS вырос, профиль покажет ту же бизнес-логику, и вы будете "чинить" то, что не сломано.
- Игнорировать инфраструктуру - проблема может быть на уровне ноды, а вы ищете в своём коде.
> Похожие задачи по backend
Используете ли трейсинг, например Jaeger
Как реализовать добавление цифр к результату с помощью append и слайса байт в Go
В чем разница наследования в Go и классического наследования
Что такое WebSocket и как он работает
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью