Сети и протоколы
Устойчивость: каскадные повторы, circuit breakers и error budget
Сторонний платёжный API замедляется до 5 секунд на ответ. Ваш сервер ждёт, получает таймаут, возвращает 503. Клиентская библиотека повторяет через 100 мс, 200 мс, 400 мс. Так делают ещё 1 000 пользователей. Ваш origin-сервер, обычно обрабатывающий 500 req/s, теперь получает 3 000 req/s — и всё ещё ждёт медленный платёжный API. Через 30 секунд весь сайт недоступен. Платёжный API был медленным, а не сломанным. Но вы превратили «медленно» в «катастрофу», повторяя запросы без координации.
Анатомия каскада
Retry storm — это положительная обратная связь: один таймаут → много повторов → больше нагрузки → больше таймаутов → больше повторов.
Математика усиления. Origin-сервер с 99,9% доступностью (1 ошибка на 1 000 запросов) в норме справляется. Во время замедления запросы скапливаются в очереди. 1 000 клиентов каждый повторяет 3 раза с наивным backoff. Трафик к origin: 3× нормы. Origin замедляется больше. Больше повторов. Через 30 секунд origin получает 10× нормального трафика. Сервер с 99,9% доступностью теперь узкое место для 100% трафика. Один деградировавший зависимый сервис превращает 0,1% ошибок в 100% отказ.
Проблема двенадцати уровней. Каждый уровень в цепочке запросов имеет свою логику повторов:
- DNS-клиент повторяет при SERVFAIL (3 попытки, каждые 2 с).
- TCP SYN повторяет при таймауте (экспоненциальный backoff, до 3 попыток).
- TLS handshake повторяет при таймауте (1–2 попытки).
- HTTP-клиентская библиотека повторяет при 5xx (3 попытки, экспоненциальный backoff по умолчанию).
- Повтор на уровне приложения (бизнес-логика повторяет неудачные вызовы сервисов).
Все двенадцать уровней повторяют независимо. Единственный сбой на уровне 6 (обработка origin) вызывает повторы на уровнях 3–12 одновременно. В совокупности один неудачный запрос становится 30+ сетевыми операциями — все они усугубляют нагрузку на и без того перегруженный origin.
| Защита | Что предотвращает | Стоимость |
|---|---|---|
| Exponential backoff + jitter | Синхронизированный thundering herd при повторах | Медленнее восстановление для отдельных клиентов |
| Circuit breaker | Повторы к отказывающему зависимому сервису | Быстрые ошибки при открытом circuit; нужна настройка |
| Bulkhead | Голодание всех потоков из-за одного медленного сервиса | Пул потоков на зависимость; сложность |
| Load shedding | Таймауты из-за глубины очереди | Быстрые ошибки 503 для избыточного трафика |
| Graceful degradation | Полный отказ при недоступности origin | Устаревшие данные; сложный дизайн кэша |
Защита 1: Exponential backoff с jitter
Наивный повтор. Клиент видит 503, повторяет немедленно. Сервер всё ещё сломан. Клиент видит 503, повторяет снова. Сервер никогда не восстанавливается.
Экспоненциальный backoff. Первый повтор через 100 мс, второй через 200 мс, третий через 400 мс, четвёртый через 800 мс (удвоение каждый раз, ограниченное максимумом). Origin получает время для восстановления между повторами.
Почему jitter необходим. Если 1 000 клиентов все достигают предела и все используют одни параметры backoff, они все повторяют в t=100 мс, t=200 мс и т.д. одновременно. Origin получает всплеск каждые 100 мс — thundering herd. Jitter: добавить ±25% случайной вариации к каждой задержке повтора. 1 000 клиентов распределяют повторы по окну 200 мс. Нагрузка на origin постоянная, а не импульсная.
Формула полного jitter (Jeff Atwood / Amazon): sleep = random_between(0, min(cap, base * 2^attempt)). Это даёт до cap мс сна на последней попытке, полностью рандомизированный — наиболее эффективный против thundering herd.
Защита 2: Circuit breaker
Паттерн из электротехники: переключатель, который размыкается при превышении тока порога, предотвращая каскадный ущерб.
Три состояния:
- Closed (замкнутый) (норма). Запросы проходят. Мониторится частота ошибок и задержка.
- Open (разомкнутый) (сработавший). Частота ошибок или задержка превысила порог для последних N запросов. Новые запросы немедленно отказывают (быстрая ошибка, без сетевого вызова). Сервер не опрашивается.
- Half-open (полуоткрытый) (зонд). После окна остывания (например, 30 с) один запрос пропускается. Если успешен, circuit закрывается (норма). Если неуспешен, circuit снова размыкается.
Почему быстрый отказ помогает. Если circuit открыт и возвращает 503 за <1 мс, клиент завершается быстро. С exponential backoff + jitter клиент ждёт и повторяет. Origin получает облегчение. Когда origin восстанавливается, полуоткрытый зонд успешен и трафик возобновляется. Без circuit breaker клиент продолжает повторять секундами — добавляя нагрузку на и без того перегруженный origin.
Реализация. Библиотеки: Netflix Hystrix (Java, deprecated), Resilience4j (Java), Polly (.NET), opossum (Node.js). Конфигурация: порог отказов (например, 50% ошибок за последние 10 запросов), остывание half-open (30 с), размер скользящего окна.
Защита 3: Bulkhead
Назван по аналогии с переборками корабля, изолирующими затопление в одной секции. В ПО: давать каждому зависимому сервису отдельный пул потоков (или async семафор). Если платёжный API медленный, он заполняет пул потоков платежей. Пулы потоков user API, product API и CDN-fetch остаются доступными. Медленный зависимый сервис не голодит все потоки.
Без bulkheads. Общий пул потоков из 100. Платёжный API замедляется → 100 запросов в очереди → все 100 потоков заняты → каждый API endpoint (user, product, search) заблокирован. Сайт недоступен для всех функций, а не только для платежей.
С bulkheads. Платежи: 20 потоков. Пользователи: 30 потоков. Продукты: 30 потоков. Прочее: 20 потоков. Платёжный API замедляется → 20 потоков платежей заняты → платёжный endpoint медленный → все остальные endpoints не затронуты. Graceful частичная деградация.
Защита 4: Load shedding
Когда очередь запросов превышает мощность сервера для обработки, сбрасывайте излишек с быстрым 503 вместо того, чтобы ждать таймаутов.
Почему быстрый 503 лучше таймаута. Запрос, в итоге завершившийся таймаутом через 30 с, удерживает поток, соединение с БД и память 30 с. Запрос, получивший 503 за <1 мс, немедленно освобождает все ресурсы. Клиент может повторить с backoff. Сервер остаётся стабильным.
Реализация. Nginx: limit_req_zone + limit_req (на основе скорости, возвращает 503 при заполнении очереди). В приложении: проверять глубину очереди запросов; если > порога, возвращать 503 немедленно. Сочетать с stale-while-revalidate на CDN, чтобы кэшированный контент всё ещё обслуживался с edge при перегрузке origin.
Error budget и SLO-ориентированный release cadence
SLO (Service Level Objective). SLO на 99,9% доступности за 30-дневное окно означает, что сервис может иметь 0,1% ошибок — около 43,2 минут простоя. SLO 99,95% допускает ~21,6 минут.
Error budget. Допустимое время отказов. Когда бюджет сжигается:
- При 50% использовании: замедлить рискованные изменения (релизы функций, изменения конфигурации).
- При 100% использовании: заморозить все несущественные релизы до улучшения надёжности.
Это формализует компромисс задержка/скорость выпуска без политики. Инженеры могут выпускать быстро, пока есть бюджет; эксплуатация может применять заморозку релизов, когда бюджет исчерпан.
Performance budgets. Распространить ту же идею на загрузку страницы: установить явные цели (LCP < 2,5 с, бандл JS < 200 КБ). Применять в CI инструментами типа bundlewatch, size-limit, Lighthouse CI. Сборка, превышающая бюджет, падает в pipeline. Заставляет делать осознанные компромиссы при PR вместо обнаружения раздутости в продакшне.
Почему это работает
Error budget разрешает классическое противоречие надёжность-скорость. Вместо споров инженерной команды и продукта «можно ли выпустить это рискованное изменение», error budget отвечает математически: если у вас осталось 30 минут бюджета в этом месяце, изменение с 20% вероятностью инцидента на 5 минут стоит риска (ожидаемая стоимость: 1 минута); изменение с 20% вероятностью инцидента на 45 минут — нет (ожидаемая стоимость: 9 минут > бюджет 30 минут). Количественный риск заменяет мнение.
Каскадный retry storm от DDoS-атаки с усилением: как единственный отказ на уровне 11 каскадирует через все двенадцать уровней.
Продукт для совместной работы в реальном времени требует p95 задержки менее 100 мс глобально для редактирования документов.
Спроектируйте архитектуру пути запросов для глобального SaaS, который должен соответствовать: p95 загрузка страницы 1 с, p95 API-вызов 200 мс, доступность 99,99%.
- Глобальная пользовательская база, преимущественно Северная Америка + Европа + Азия.
- Преимущественно read-трафик; часть write-трафика для аккаунтов пользователей и правок документов.
- Требования compliance: данные пользователей ЕС должны оставаться в ЕС.
- Кэшировать статику на edge; маршрутизировать динамику через edge gateway к региональным кластерам.
- Региональное хранение данных через row-level policy + региональные реплики.
- Распределённая трассировка OpenTelemetry end-to-end с tail-based семплированием ошибок.
- Circuit breakers на каждый сторонний зависимый сервис.
- Performance budgets, применяемые в CI — регрессии видны при PR.
- Error budget (99,99% = 4,38 мин/месяц) управляет release cadence — заморозка при исчерпании бюджета.
Каков error budget для SLO доступности 99,95% за 30-дневное окно?
Circuit breaker находится в состоянии OPEN. Приходит новый запрос. Что должно произойти?
- 01Объясните математику усиления: как сервер с 99,9% доступностью полностью падает при retry storm?
- 02Почему добавление jitter к exponential backoff предотвращает thundering herd и какова формула полного jitter?
- 03Старший архитектор утверждает, что edge compute всегда лучше региональных origin. Где ошибка в этом аргументе?
Каскадные retry storm возникают потому, что каждый уровень в двенадцатифазной цепочке запросов имеет независимую логику повторов — когда зависимый сервис замедляется, все уровни повторяют одновременно, усиливая трафик с 1× до 10× менее чем за минуту. Стек защиты: exponential backoff с полным jitter (распределяет повторы), circuit breakers (быстрая ошибка при отказе, half-open зонд для восстановления), bulkheads (пул потоков на зависимость для сдерживания радиуса поражения) и load shedding (быстрый 503 при превышении глубины очереди). Error budget формализует компромисс скорость/надёжность: SLO 99,95% допускает 21,6 минут простоя за 30-дневное окно; исчерпание бюджета вызывает заморозку релизов, а не спор. Полная архитектура для глобального SaaS сочетает CDN edge для статики, региональные Kubernetes-кластеры с региональным хранением данных, OpenTelemetry с tail-based семплированием ошибок и CI-применяемые performance budgets — рассматривая каждый уровень как потенциальный домен отказа с явными runbook.
встречается в269
- Почему GraphQL получает N+1junior
- Механика DataLoader: батчинг на границе тикаmiddle
- Контракты batch-функции: порядок, формы, ошибкиmiddle
- Federation и lookahead: батчинг за пределами DataLoadermiddle
- Защита сложности запросов: depth, cost, persisted queriesmiddle
- Senior GraphQL API: scheduling-контракт, изоляция арендаторов, наблюдаемостьsenior
- Путь запроса: семь остановок от сокета до ответаjunior
- Accept и парсинг: от очереди ядра до типизированного запросаmiddle
- Маршрутизация и middleware: что выполняется и в каком порядкеmiddle
- Обработчик и ответ: от бизнес-логики до байтов на проводеmiddle
- Стриминг и backpressure: когда клиент читает медленнее, чем вы пишетеsenior
- Таймауты и хвостовая задержка: бюджеты, дедлайны и ловушка fan-outsenior
- Middleware и DI: два паттерна, формирующие любой backendjunior
- Пишем middleware: сигнатуры, next() и три модели фреймворковmiddle
- Инверсия управления: как зависимости добираются до классаmiddle
- Скоупы и время жизни DI: singleton, request, transientmiddle
- DI как шов для тестов: фейки, моки и граница, которая важнаsenior
- DI-контейнеры в продакшене: графы разрешения, циклы и когда не стоитsenior
- Блокирующий vs неблокирующий I/O: два способа ждатьjunior
- Event loop: один поток, упорядоченные фазыmiddle
- Что блокирует цикл: CPU-работа и синхронные вызовыmiddle
- Вынос CPU-работы: worker threads и пул libuvmiddle
- Backpressure и ограниченная конкурентностьsenior
- Пропускная способность под нагрузкой: хвостовая задержка и насыщениеsenior
- Зачем пул: цена создания соединенияjunior
- Размер пула: почему больше не значит быстрееmiddle
- Взятие и таймауты: очередь ожидания — настоящий дроссель задержкиmiddle
- Зачем идемпотентность: безопасные retryjunior
- Серверный state machine: четыре состояния idempotency keymiddle
- Стратегии retry: backoff, jitter и thundering herdmiddle
- Outbox и inbox: effectively-once через dual-write границуmiddle
- Конкурентность и архитектура кеша для идемпотентности на масштабеsenior
- Наблюдаемость, production-инциденты и дизайн для глобального масштабаsenior
- Event loop: один поток, три очередиjunior
- Задачи, микрозадачи и scheduler.yield()middle
- Точность таймеров, троттлинг и фоновая работаmiddle
- Голодание микрозадач, длинные задачи и LoAFsenior
- Event loop Node.js: фазы, nextTick и задержка циклаsenior
- React, Vue и наблюдаемость INP в продакшенеsenior
- Render pipeline: шесть стадий от байтов до пикселейjunior
- Цена стадий и модель процесса рендерераmiddle
- Инвалидация, dirty-биты и containmiddle
- Слои композитора: продвижение, перекрытие и память GPUmiddle
- Флейм-стрип DevTools и жизненный цикл кадраmiddle
- Layout thrash: форсированная синхронная компоновкаsenior
- BeginMainFrame, анимации на потоке compositor и память GPUsenior
- Observability в проде: LoAF, INP и полная поверхность атакиsenior
- Что такое V8 и почему производительность различается в 100 разjunior
- Четырёхуровневый JIT-конвейер V8 и профилированная тиеризацияmiddle
- Hidden classes, деревья переходов и расположение в памятиmiddle
- Inline caches, состояния IC и деоптимизацияmiddle
- Orinoco GC: параллельный scavenger, конкурентная разметка и барьеры записиmiddle
- Спекулятивный движок TurboFan и ловушка deopt-loopsenior
- V8 в production: Isolates, сжатие указателей и реальные аварииsenior
- Что такое воркеры и зачем они нужныjunior
- Механика web workers: dedicated, shared и OffscreenCanvasmiddle
- Structured clone и transferablesmiddle
- Жизненный цикл service worker и стратегии кешированияmiddle
- SharedArrayBuffer, Atomics и cross-origin isolationsenior
- Граничные случаи service worker: version skew, долговременность и ловушка навигацииsenior
- Пулы воркеров, Comlink и наблюдаемость в продакшенеsenior
- Что делает реконсилер: render vs commitjunior
- Объект fiber и дерево с двойной буферизациейmiddle
- Чистота фазы render и подшаги фазы commitmiddle
- Реконсиляция: эвристики диффа и ловушка ключейmiddle
- Приоритетные lanes, time-slicing и useTransitionmiddle
- Bailout, мемоизация и tearingsenior
- React Profiler, компилятор и продакшн-наблюдаемостьsenior
- Стратегии рендеринга: SSG, SSR, ISR, streaming и гидратацияjunior
- SSG, SSR, ISR, streaming и RSC — как работает каждая стратегияmiddle
- Цена гидратации: selective, progressive, острова, resumabilitymiddle
- Hydration mismatch: причины, обнаружение и правило детерминизмаsenior
- RSC, стратегия на маршрут и production-наблюдаемостьsenior
- Core Web Vitals: что измеряют LCP, INP и CLSjunior
- LCP: четыре фазы, одна доминирующая стоимостьmiddle
- INP: input delay, processing, presentationmiddle
- CLS: почему происходят сдвиги лейаута и как их остановитьmiddle
- Lab vs field: почему они расходятся и как использовать каждыйmiddle
- Трейдоффы метрик, RUM-атрибуция и цикл CI+полеsenior
- Общая картина: от URL до LCP до INP как эстафетаjunior
- Восемь слоёв трассировки: от service worker до второй навигацииmiddle
- Пять канонических поломок: где производство стабильно ломаетсяsenior
- Метод трёх треков: чтение трасс и построение системы мониторингаsenior
- Что такое cache stampede и почему он делает всё хужеjunior
- Лок и single-flight: ограничение параллельных rebuildmiddle
- XFetch: вероятностное раннее истечение без координацииmiddle
- Stale-while-revalidate и CDN request coalescingmiddle
- Детектирование stampede и дизайн TTL для продакшенаmiddle
- Метастабильный сбой, fencing-токены и production-постмортемыsenior
- Что такое отношение: таблицы, строки, ключи и ограниченияjunior
- Ограничения, ключи и типы данных Postgresmiddle
- Нормальные формы, денормализация и почему схемы «прилипают»middle
- JSONB, массивы и когда side table побеждаетmiddle
- Heap-хранилище, TOAST и выравнивание колонокsenior
- Целостность схемы: deferral, версионирование и сбои в продакшнеsenior
- Реляционная модель vs документные, wide-column, граф и key-valuesenior
- Что такое индекс и как он ускоряет запросыjunior
- Leading-column rule: почему порядок столбцов в composite-индексе важенmiddle
- Partial, expression и covering-индексыmiddle
- Типы индексов: GIN, GiST, BRIN, Hash, Bloom и HOT-обновленияmiddle
- Index-only scan, Visibility Map и INCLUDEsenior
- Типичные сбои в продакшне и аудит индексовsenior
- Упражнение по проектированию индексов: стратегия полнотекстового поискаsenior
- EXPLAIN и планы выполнения: что решает планировщик и почемуjunior
- Типы сканирования: Seq, Index, Bitmap, Index-Onlymiddle
- Алгоритмы соединения и каскад ошибок оценки строкmiddle
- pg_statistic, ANALYZE и производственная наблюдаемостьmiddle
- Расширенная статистика: исправление ошибок оценки для коррелированных колонокsenior
- Кеш планов, настройка константных стоимостей и внутренности планировщикаsenior
- Производственные режимы отказа и стабильность плановsenior
- MVCC: как Postgres раздаёт согласованные снимкиjunior
- Заголовок tuple и механика снимковmiddle
- HOT-обновления и уровни изоляцииmiddle
- VACUUM, bloat и autovacuummiddle
- CLOG, XID wraparound и MultiXactsenior
- SSI и production-тюнинг autovacuumsenior
- Реальные провалы MVCC, deployment-паттерны и распределённые снимкиsenior
- Connection pool: зачем амортизировать стоимость backend Postgresjunior
- Режимы PgBouncer: session, transaction и statementmiddle
- Размер пула: формула (ядра × 2) + шпинделей и двухуровневый стекmiddle
- Исчерпание пула и idle-in-transaction: сценарий отказа в 3 ночиmiddle
- Миграция на transaction mode: план развёртывания и prepared statements в PgBouncer 1.21middle
- Процессная модель Postgres и почему увеличение max_connections снижает производительностьsenior
- Ландшафт пулеров 2026, serverless connection storms и полная таксономия отказовsenior
- Что такое миграция схемы и почему она заменяет ad-hoc DDLjunior
- ADD COLUMN: мгновенно в PG 11+ против перезаписи в старом Postgresjunior
- Режим отказа очереди блокировок: почему мгновенный DDL может заморозить базуmiddle
- Безопасные DDL-паттерны: NOT VALID, CONCURRENTLY и исправления небезопасных операцийmiddle
- Expand-contract: нулевой простой для ломающих изменений схемыmiddle
- Advisory-блокировки, инструменты миграций и координация деплояsenior
- Таксономия сбоев миграций и дисциплина продакшнаsenior
- Зачем нужно шардирование: потолок одного Postgresjunior
- Выбор ключа шарда: стратегии hash, range, list и directorymiddle
- Партиционирование против шардирования: одно слово, два разных понятияmiddle
- Ко-локация и Citus: инвариант, делающий шардирование пригодным к использованиюmiddle
- Режим отказа hot shard: обнаружение, изоляция и долгосрочная политикаmiddle
- Schema-based шардирование и альтернативы мультиарендностиsenior
- Онлайн-решардинг, 2PC и операционная стоимость шардированияsenior
- Семь актов: от CREATE TABLE до Citusjunior
- Акты 1–3 в глубину: схема, индексы и статистика планировщикаmiddle
- Акты 4–6 в глубину: MVCC bloat, connection pooling и безопасные миграцииmiddle
- Акт 7 в глубину: шардинг, co-location и семиуровневый каскад трейдоффовmiddle
- Наблюдаемость, антипаттерны и производственный триажsenior
- Роли Raft, term и почему majority-кворум предотвращает split brainjunior
- Как Raft реплицирует log entry и решает, что его безопасно коммититьmiddle
- Выборы лидера в Raft: таймауты, правила голосования и четыре свойства безопасностиmiddle
- Raft в реальном мире: partition, медленный диск и клиентская маршрутизацияmiddle
- Расширения Raft: pre-vote, learner, snapshot и линеаризуемые чтенияsenior
- Raft в production: membership change, Multi-Raft и observabilitysenior
- Где происходит data fetching — и почему это решает LCPjunior
- Fetch waterfall''''ы — диагностика и лечение через Promise.allmiddle
- React Server Components и Suspense streamingmiddle
- Клиентский кэш: TanStack Query, SWR и stale-while-revalidatemiddle
- LCP, prefetch и race conditions в интерактивном fetchingmiddle
- Senior internals: RSC payload, слои кэша и production паденияsenior
- Что такое три сигнала: метрики, логи, трейсыjunior
- Метрики и cardinality: cost-модель time-series databasemiddle
- Логи и объём: cost-модель структурного логированияmiddle
- Трейсы и сэмплирование: cost-модель distributed tracingmiddle
- Join-ключи и exemplar''''ы: как три сигнала становятся компонуемымиmiddle
- Observability 2.0: широкие события и сдвиг стоимостиsenior
- Режимы сбоя и инженерная практика: cardinality budget''''ы, PII и сэмплированиеsenior
- Зачем нужны структурные логи: дневник против таблицыjunior
- Схема продакшн-лога: поля, которые несёт каждая строкаmiddle
- Log levels и маршрутизация алертовmiddle
- Стратегии sampling и стоимость логовmiddle
- PII-редакция и log injectionsenior
- Propagation trace-контекста в логахsenior
- OTel Logs Data Model и audit-логи как подсистемаsenior
- Что такое OpenTelemetry: API, SDK, Collector, OTLPjunior
- Сигналы OTel, Semantic Conventions и проводной формат OTLPmiddle
- Авто-инструментирование и ручные спаны: правило 80/20 в OTelmiddle
- Collector OTel: receivers, processors, exporters и паттерны развёртыванияmiddle
- Стратегии сэмплирования: head, tail и parent-basedmiddle
- Vendor-нейтральность, eBPF-инструментирование, Operator и OTel в браузере и serverlesssenior
- Эксплуатация OTel Collector: надёжность, version skew, режимы отказа и управлениеsenior
- RED и USE: два чек-листа, одна дисциплина триажаjunior
- Инструментация RED в Prometheus: счётчики, гистограммы и дисциплина cardinalitymiddle
- USE на Linux: CPU, память, диск, сеть и PSImiddle
- Golden signals, структура дашборда и auto-RED в service meshmiddle
- Cardinality как драйвер затрат: label, PII, exemplars и семплированиеmiddle
- Native histograms, SLO и паттерны production-сбоевmiddle
- SLI, SLO и error budget: надёжность в числахjunior
- Выбор SLI и SLO-целей: отношения, не ощущенияmiddle
- Multi-window multi-burn-rate-алертинг: почему AND лучше ORmiddle
- Error budget policy, latency SLO и составные journeysmiddle
- Iceberg SLI, математика составного SLO и SLA vs SLOsenior
- Продакшн-отказы SLO, самонаблюдаемость, безопасность и общая картинаsenior
- Что такое trace propagation и почему сломанная propagation хуже отсутствия трейсовjunior
- traceparent и tracestate: полный формат W3C-заголовкаmiddle
- Baggage и async-границы: перенос контекста через очереди и callback''''иmiddle
- Async context на разных языках, service mesh, миграция B3 и безопасностьsenior
- Production-сбои propagation, span links и платформенный дизайнsenior
- Flame graph: читаем картинку, которая показывает, куда ушло времяjunior
- Sampling vs instrumentation profiling: почему 99 Гц побеждает в productionmiddle
- Типы профилей: CPU, память, off-CPU, mutex — какой когда братьmiddle
- Continuous profiling: always-on flame graphs с eBPF и корреляцией trace-idmiddle
- Как flame graph строится из сэмплов и как использовать его в productionmiddle
- Linux perf, внутренности eBPF, PGO и ограничения sampling''''аsenior
- Profiling в production: безопасность, war stories, OTel profiles и дизайн инфраструктурыsenior
- Debugging-воронка: SLO → RED → trace → profilejunior
- Архитектура OTel: один SDK, четыре сигнала, один wire-форматmiddle
- Экономия на observability: удерживаем затраты в пределах 5% inframiddle
- Петля инцидента: от пейджера до постмортема до предотвращенияmiddle
- Масштаб, безопасность и ROI наблюдаемых системsenior
- Сначала профиль: измерь куда реально уходит времяjunior
- Закон Амдала и self-time: потолок любого ускорения, которое ты можешь выпуститьmiddle
- Измерительный цикл: микробенч, макробенч, prod-профиль, эффект наблюдателяmiddle
- Чтение флейм-графов: формы, профайлеры по языкам и 60-секундный сканmiddle
- Статистические baseline''''ы: почему один запуск — не измерениеmiddle
- История профайлеров и ловушки микробенчей: от Кнута до GWPsenior
- Hardware counters, профили холодного старта и безопасность профилейsenior
- Непрерывное профилирование в масштабе: затраты, CI-гейты, корреляция с трейсами и антипаттерныsenior
- Что делает путь горячим: симптом против причиныjunior
- Пять форм hotspot''''а: CPU, аллокации, кэш, лок, syscallmiddle
- Чтение parent и child chains: где применять правкуmiddle
- JIT deopt, цикл fix-and-verify и PR-time профилированиеmiddle
- Аппаратные счётчики и Intel TMA: диагностика подкатегорийsenior
- False sharing и горячие пути нативных мостовsenior
- Горячие пути в production: безопасность, хвостовая латентность и происхождение инструментовsenior
- Иерархия памяти: почему расстояние важнее числа операцийjunior
- Row-major vs column-major: порядок доступа и разрыв в 9xjunior
- Cache lines и false sharing: когда параллелизм замедляет кодmiddle
- Branch prediction: 10–30 циклов штрафа за неожиданный ifmiddle
- SIMD и data layout: AoS vs SoA и разница в 4–8xmiddle
- Hardware prefetcher, TLB и memory-level parallelismsenior
- Cache-oblivious алгоритмы, PGO и production failuressenior
- Основы GC: за что рантайм берёт налогjunior
- Алгоритмы GC: поколенческая гипотеза, concurrent marking и write barriermiddle
- GC tradeoffs: пауза, throughput, память и давление аллокацийmiddle
- Настройка GC: пейсинг, форма кучи и наблюдаемость аллокацийmiddle
- Внутреннее устройство GC: tri-color инвариант, write barriers и глубокое погружение в рантаймыsenior
- GC в production: наблюдаемость, безопасность, edge cases и управление флотомsenior
- N+1: одна логическая операция, много round-trip''''овjunior
- Семейства фиксов: JOIN, IN, preload и DataLoadermiddle
- Обнаружение N+1: query logs, APM traces и CI gatesmiddle
- DataLoader: батчинг по дереву резолверовmiddle
- Кросс-протокольный N+1: HTTP fan-out и Redis MGETmiddle
- N+1 в масштабе: исчерпание пула, изменения планов и денормализацияsenior
- Batching: амортизируй фиксированную цену каждой операцииjunior
- Окно батчинга: размер и время ожиданияmiddle
- Batching в Kafka и Postgresmiddle
- io_uring и наблюдаемость пакетированияmiddle
- От Nagle до io_uring: эволюция пакетированияmiddle
- Backpressure, изоляция сбоев и безопасность батчей в продакшенеsenior
- Что на самом деле стоит bundle: download, parse, compile, executejunior
- Core Web Vitals: LCP, INP и CLSmiddle
- Code splitting: route-level, component-level, vendor splittingmiddle
- Tree shaking и compression: удаляем то, что не используемmiddle
- Third-party scripts: тихий убийца бюджетаmiddle
- CI enforcement и RUM: делаем бюджеты рабочимиmiddle
- V8 JIT-пайплайн, HTTP-приоритеты и безопасность bundlesenior
- Цикл performance: дисциплина, а не проектjunior
- Классификация и исправление: сопоставление family bottleneck с методамиmiddle
- Observability-стек и CI gates: ловить регрессии до выпускаmiddle
- От инцидента к enforcement: SLO burn до верифицированного исправления за 35 минутmiddle
- Культура, экономика и масштаб performancesenior
- At-most-once, at-least-once, exactly-once: три контракта доставкиjunior
- Три ножки сбоя — где реально происходят дубликаты и потериmiddle
- Consumer-side dedup: самый дешёвый путь к exactly-once processingmiddle
- Kafka exactly-once semantics: idempotent producer и транзакцииmiddle
- SQS visibility timeout, DLQ и outbox patternmiddle
- Exactly-once в production: impossibility-доказательство, гибридные паттерны и реальные инцидентыsenior
- Что такое OAuth и почему пароли — не ответjunior
- Authorization code flow с PKCEmiddle
- Валидация ID-токена и управление JWKS-кешемmiddle
- Ротация refresh-токенов и scope-based least privilegemiddle
- Sender-constrained токены: DPoP и mTLSsenior
- OAuth в production: audience атаки, observability и реальные провалыsenior