TGViewer
Art of Code Art of Code @codeof_art · 2.17K subscribers
Post #338 234
Новый пост из серии про паттерны на реальном коде. Разбираем штуку, с которой рано или поздно встречается любой сервис, живущий в интернете: в него начинают лить больше, чем он способен переварить.

Ситуация простая. У тебя есть сервис, который что-то принимает извне — запросы, события, сообщения. И в какой-то момент поток на входе становится больше, чем ты успеваешь обрабатывать. Причины разные: у клиента выкатили баг, и он спамит одним и тем же по кругу; резкий наплыв пользователей; банальный DDoS. Если просто сидеть и принимать всё подряд, исход один из двух — либо сервис ложится под нагрузкой, либо копит необработанное в памяти, пока она не кончится, и падает уже намертво. Защита от этого называется backpressure: сервис не молча захлёбывается, а сам говорит источникам «э, притормозите».

Разберём на Sentry. Если не знаком: это сервис, куда приложения шлют информацию о своих ошибках и падениях — упало что-то в проде, полетел отчёт с деталями, разработчики видят его в удобном интерфейсе, а не роются в логах. Нагрузка у неё дикая: тысячи чужих приложений долбят её событиями безостановочно. На входе у Sentry стоит отдельный компонент — Relay, он первым встречает весь этот поток и решает, что с ним делать. На нём и посмотрим, как грамотно держать удар. Код открыт: https://github.com/getsentry/relay

Первое, что там сделано с умом, — ограничение стоит не одним общим рубильником на всё, а раздельно, по типам данных и по каждому проекту. Можно прижать один вид событий у одного клиента, не задев остальной трафик. Клиенту, который упёрся в лимит, прилетает ответ 429 и заголовок с числом: «подожди столько-то секунд». И вот ключевая тонкость: правильный клиент в ответ на это НЕ шлёт то же самое заново — он выбрасывает событие и ждёт. Потому что если в ответ на «перегруз» все дружно начнут повторять запросы, они этим перегруз только усилят. В этом и суть backpressure: смысл ответа — «перестань слать вообще», а не «попробуй ещё разок». Обычная ошибка говорит «повтори», backpressure говорит «уймись» — это разные вещи.

Второй умный момент — как Relay хранит сами лимиты. Он держит их в памяти и освежает раз в несколько минут, а не бегает во внешнее хранилище на каждое событие (иначе оно само стало бы узким горлышком). Отсюда забавная деталь: самый первый запрос, упёршийся в свежий лимит, может ещё проскочить с ответом 200 — просто потому что в памяти лимит ещё не обновился, а следующий уже получит честный отказ. Осознанный размен: чуть менее точно, зато во много раз дешевле под нагрузкой. Клиентов, которые давно в лимите, Relay отшивает вообще бесплатно — их «приговор» уже лежит в памяти.

Третий уровень — что делать с тем, что уже приняли, но обработать пока не успели. Relay складывает такие события в очередь в памяти, но следит за её размером: пока памяти занято меньше порога (по умолчанию 80%) — держит очередь в ней, ради скорости. Перевалило за порог — начинает скидывать на диск. Медленнее, зато не сожрёт всю память и не рухнет, пока разгребает завал. Такой буфер сглаживает всплеск: не теряем события и не падаем от переполнения памяти.

Теперь — как это утащить к себе, даже без всякого Sentry. Принцип работает везде, где что-то принимает поток извне. Пишешь API, которое дёргают чужие сервисы? Отдавай на перегрузе честный 429 с «подожди столько-то», а не пытайся героически переварить всё и не роняй сервер. Обрабатываешь очередь сообщений? Следи за её длиной и умей притормозить того, кто в неё пишет. Ходишь во внешний API сам? Уважай его 429 и не ретрай мгновенно — ты этим только добьёшь того, кто и так лежит.

И три мысли на вынос. Лимиты делай точечными, а не «рубильник на всё сразу». Сигнал перегруза — это «перестань», а не «повтори», и клиенты должны его уважать. И заранее думай, что делать с тем, что уже принял, но не осилил, — буфер с выходом на диск лучше, чем гордое падение. Наивное «очередь большая — верну 500» не делает ничего из этого, поэтому и падает первым.

Подписаться: @codeof_art
Вступить в чатик: @code_of_art
  • ❤ 3
  • ⚡ 2
More from @codeof_art
  1. Sep 21, 2026Полный цикл собесов в Яндекс (Бэкенд 2026) Сейчас студенты наших курсов под чутким сопрово…
  2. Sep 20, 2026❗️ Яндекс открыл Intern Week Offer на стажировку, где всего за неделю ты можешь получить о…
  3. Sep 19, 2026Товарищи, Поступашкам нужны контент мейкеры в основной канал по алгоритмам и другим дисцип…
  4. Sep 17, 2026System Design: backend Сегодня разберём задачу, которую мне давали на собесе в Яндекс. Шту…
  5. Sep 16, 2026В Яндекс без опыта с первого раза Товарищи, продолжаем рассказывать про наших талантливых…
  6. Sep 16, 2026Сходил на собеседование в Шушу. Предложили интересную задачу: спроектировать агрегатор про…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →