Трейсы показывают, что запрос занял 800 мс. Метрики подтверждают: p99 вырос в 3 раза после деплоя. Но ни то, ни другое не объяснит, какая строчка кода потребляет 40% CPU. Для этого нужен профайлер, работающий в production непрерывно. Continuous Profiling — постоянная запись профилей (flamegraph'ов) всех процессов. За 5 лет практики находили сотни узких мест: от JSON-сериализации в hot path до утечек памяти в middleware. Внедрение Pyroscope или Parca позволяет не просто находить проблемы, но и предотвращать регрессии при каждом деплое. Свяжитесь с нами, чтобы обсудить внедрение Continuous Profiling в вашем проекте.
Почему стоит использовать Continuous Profiling вместо разовых профайлеров?
Разберёмся, что даёт непрерывный мониторинг. Разовый py-spy top даёт срез здесь и сейчас. Continuous profiling даёт историю. Если сегодня p95 CPU 70%, а неделю назад было 50% — flamegraph покажет, какой коммит это вызвал. Без истории вы будете гадать, когда началась деградация. Кроме того, Pyroscope и Parca в 2–3 раза быстрее помогают расследовать инциденты за счёт готовой временной шкалы. Вы можете смотреть, как менялся flamegraph с каждым деплоем — это снижает MTTR с часов до минут. По данным наших проектов, экономия времени на отладку достигает 40%, а затраты на инфраструктуру — 15-20%.
Какие проблемы решает Continuous Profiling?
Рассмотрим конкретные сценарии.
Утечки памяти, которые не видны в метриках
Обычные container_memory_usage_bytes показывают рост, но не указывают на виновника. Профайлер heap'а (Pyroscope ProfileInuseObjects) точно показывает, какой объект и какая функция держат память. В одном из проектов нашли утечку в middleware, которая за 6 часов поднимала RSS процесса с 200 МБ до 2 ГБ — flamegraph сразу указал на код, неправильно работающий с context.Context.
Регрессии CPU после деплоя
Выкатили новую версию — CPU вырос на 300%. Flamegraph 'до' и 'после' показывает, какая функция стала медленнее. Типичные находки: неожиданное включение отладки, изменение уровня логирования, новая зависимость с тяжёлыми regexp.
Корреляция с трейсами
При медленном trace, указывающем на span длительностью 500 мс, flamegraph за тот же период покажет, какая функция внутри span заняла 80% времени. Pyroscope поддерживает middleware для OpenTelemetry и Jaeger — profile.id записывается в span автоматически.
Какой инструмент выбрать: Pyroscope или Parca?
| Характеристика | Pyroscope (Grafana) | Parca (PolarSignals) |
|---|---|---|
| Модель работы | Push-mode (SDK) + Pull-mode (eBPF) | Только Pull-mode (eBPF) |
| Необходимость изменений в коде | Push-mode — да, Pull-mode — нет | Нет |
| Поддерживаемые языки | Java, Go, Python, Node.js, Ruby (Pull) | Любые процессы на ноде |
| Интеграция с трейсами | Встроенная (OpenTelemetry, Jaeger) | Только через лейблы |
| Оверхед CPU | 1–5% (Pull 1-3%, Push 2-5%) | 1-3% |
| Хранение | S3, GCS, локальный | S3, GCS, локальный |
Получите консультацию по выбору инструмента и настройке.
Как мы настраиваем Continuous Profiling
Pyroscope: pull mode (eBPF агент)
Pyroscope Agent запускается как DaemonSet, читает профили напрямую из ядра через eBPF без изменений в приложениях. Требует Kubernetes 1.19+ и ядро Linux 4.9+.
# pyroscope-values.yaml для Helm pyroscope:
replicaCount: 1
storage:
backend: s3
s3:
bucket: my-pyroscope-profiles
region: eu-west-1
agent:
enabled: true
tolerations:
- operator: Exists # деплоить на все ноды включая system
config:
discovery.relabel "pods" {} # автодискавери подов
Как работает eBPF?
eBPF — это технология ядра Linux, которая позволяет запускать изолированные программы в ответ на события (системные вызовы, сетевые пакеты и т.д.). В контексте profiling eBPF позволяет сэмплировать стек вызовов всех процессов без изменения их кода. Оверхед минимален, так как сбор происходит на уровне ядра.Pyroscope: push mode (SDK)
Приложение явно шлёт профили в Pyroscope. Даёт лучший контроль над лейблами и меньший оверхед для конкретных сервисов.
Go SDK:
import "github.com/grafana/pyroscope-go"
func main() {
pyroscope.Start(pyroscope.Config{
ApplicationName: "order-service",
ServerAddress: "http://pyroscope:4040",
Tags: map[string]string{
"version": os.Getenv("APP_VERSION"),
"region": os.Getenv("REGION"),
},
ProfileTypes: []pyroscope.ProfileType{
pyroscope.ProfileCPU,
pyroscope.ProfileAllocObjects,
pyroscope.ProfileAllocSpace,
pyroscope.ProfileInuseObjects,
pyroscope.ProfileInuseSpace,
},
})
// ...
}ProfileAllocObjects и ProfileInuseObjects — heap-профили для поиска memory leaks. Именно они помогли найти утечку в middleware, которая за 6 часов поднимала RSS процесса с 200MB до 2GB. Изучите Pyroscope для углублённого понимания.
Parca: eBPF-ориентированная альтернатива
Parca 100% построен на eBPF, более минималистичен, не требует изменений в коде приложений.
helm install parca parca/parca \
--set parca.config.object_storage.bucket.type=S3 \
--set parca.config.object_storage.bucket.config.bucket=my-parca-profiles Процесс внедрения
| Этап | Длительность | Описание |
|---|---|---|
| Аудит текущего стека и целей | 1 день | План профилирования: какие сервисы, какие метрики, частота сэмплирования. |
| Развёртывание Pyroscope/Parca | 1–2 дня | DaemonSet/Helm-релиз с хранением в S3, дашборды в Grafana. |
| Интеграция SDK (push-mode) | 1–2 дня на 5 сервисов | Код с SDK, протестированный в staging. |
| Корреляция с трейсами и метриками | 1 день | Middleware для OpenTelemetry/Jaeger, ссылки из Tempo в Pyroscope. |
| Обучение команды | 0.5 дня | Документация, runbook, разбор типичных flamegraph'ов. |
Что входит в работу
- Документация архитектуры и конфигурации (runbook).
- Доступы к дашбордам и источникам профилей.
- Обучение команды (демо-сессия 30 мин).
- Поддержка в течение 2 недель после внедрения.
Типичные ошибки при внедрении
- Слишком частая сэмплировка (1000 Hz). Даёт избыточный оверхед (до 10%). Рекомендуем 100 Hz для CPU, 50 Hz для heap.
- Хранение профилей в локальном PVC. Легко теряются; используйте S3 с retention policy.
- Отсутствие корреляции с трейсами. Без profile.id flamegraph висит отдельно — резко теряется ценность.
- Не отключать eBPF agent на нодах с высокой нагрузкой I/O. В некоторых случаях он может вызывать латенси; используйте tolerations для выделения.
Срок настройки — от 1 дня (eBPF pull mode без изменений в приложениях) до 3 дней (push mode SDK для всех сервисов + корреляция с Tempo + Grafana datasource). Стоимость рассчитывается индивидуально. Закажите аудит вашего стека для оценки необходимости Continuous Profiling. Чтобы получить консультацию по внедрению, свяжитесь с нами — мы оценим ваш проект и предложим оптимальную архитектуру.







