Сейчас все учат
И почти никто не разбирается, как базы данных работают в проде и на больших масштабах.
CMU Advanced Database Systems - Полный плейлист из 22 лекций
Освойте редкие и ценные навыки:
• Как на самом деле устроены движки выполнения запросов и оптимизаторы
• Колончатое хранение, векторизованное выполнение и современный
• Почему
• Сбои в распределённых БД и миф про «одну базу данных, которая решит всё»
👉 @BackendPortal
Next.js и AI-инструменты.И почти никто не разбирается, как базы данных работают в проде и на больших масштабах.
CMU Advanced Database Systems - Полный плейлист из 22 лекций
Освойте редкие и ценные навыки:
• Как на самом деле устроены движки выполнения запросов и оптимизаторы
• Колончатое хранение, векторизованное выполнение и современный
OLAP• Почему
Snowflake, Redshift и DuckDB всё перевернули• Сбои в распределённых БД и миф про «одну базу данных, которая решит всё»
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9🔥1
Избегайте использования
Оператор
Поскольку
Правильный способ обрабатывать
👉 @BackendPortal
IN с NULLОператор
IN относится к тем конструкциям, которые легко вносят тихие баги в запрос, если использовать его неправильно. Когда вы включаете NULL в список IN, сравнение никогда не даст TRUE для части с NULL. В результате строки, содержащие NULL, не матчятся так, как многие ожидают. SQL использует трёхзначную логику: TRUE, FALSE и UNKNOWN. Сравнения с NULL не возвращают ни TRUE, ни FALSE; они возвращают UNKNOWN. Вот наивный вариант использования IN:SELECT *
FROM Employees
WHERE DepartmentID IN (1, 2, NULL);
Поскольку
NULL даёт UNKNOWN, запрос выше выполнится без ошибок, но гарантированно вернёт пустой результат.Правильный способ обрабатывать
NULL - использовать IS NULL. IS NULL явно учитывает то, как SQL работает с отсутствующими значениями. Это помогает запросу корректно различать реальные значения и неизвестные значения, что предотвращает тихие логические ошибки. Вот как этот запрос лучше писать:SELECT *
FROM Employees
WHERE DepartmentID IN (1, 2)
OR DepartmentID IS NULL;
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Многие разработчики до сих пор по умолчанию думают в стиле:
Но в HTTP/3 под капотом используется UDP через протокол QUIC (
> HTTP/1.1 → TCP → Ориентированное на соединение, надёжное
> HTTP/2 → TCP → С мультиплексированием, но всё ещё поверх TCP
> HTTP/3 → QUIC → Построен поверх UDP ради скорости и снижения задержек
Сейчас HTTP/3 используют 38,2% всех сайтов.
👉 @BackendPortal
HTTP работает поверх TCP Но в HTTP/3 под капотом используется UDP через протокол QUIC (
Quick UDP Internet Connections).> HTTP/1.1 → TCP → Ориентированное на соединение, надёжное
> HTTP/2 → TCP → С мультиплексированием, но всё ещё поверх TCP
> HTTP/3 → QUIC → Построен поверх UDP ради скорости и снижения задержек
Сейчас HTTP/3 используют 38,2% всех сайтов.
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔4
Большинство API заявляют, что они REST.
Но на практике нарушают принципы REST почти везде.
Вот 5 самых частых ошибок, которые я постоянно вижу.
1. Глаголы в URL
Плохо
Хорошо
REST-ресурсы должны быть существительными, а не действиями.
2. Игнорирование HTTP-методов
Часто встречается такое:
Вместо
HTTP-методы придуманы не просто так.
Их нужно использовать по назначению.
3. Всегда возвращается 200
API должно чётко сигнализировать результат.
Примеры:
Статус-коды — это часть контракта API.
4. Нет пагинации
Возвращать тысячи записей в одном ответе — это ловушка для производительности.
Нужно сразу проектировать что-то вроде:
или использовать cursor-pagination.
5. Версионирование «потом как-нибудь»
Ломающие изменения в API неизбежны.
Без версионирования вы просто ломаете клиентов.
Используйте, например:
О версионировании нужно думать с самого начала.
👉 @BackendPortal
Но на практике нарушают принципы REST почти везде.
Вот 5 самых частых ошибок, которые я постоянно вижу.
1. Глаголы в URL
Плохо
/getUser
/createOrder
Хорошо
GET /users/{id}
POST /ordersREST-ресурсы должны быть существительными, а не действиями.
2. Игнорирование HTTP-методов
Часто встречается такое:
POST /updateUser
Вместо
PUT /users/{id}HTTP-методы придуманы не просто так.
Их нужно использовать по назначению.
3. Всегда возвращается 200
API должно чётко сигнализировать результат.
Примеры:
200 → успех
201 → ресурс создан
400 → неверный запрос
404 → ресурс не найден
409 → конфликт
Статус-коды — это часть контракта API.
4. Нет пагинации
Возвращать тысячи записей в одном ответе — это ловушка для производительности.
Нужно сразу проектировать что-то вроде:
GET /orders?page=1&size=20
или использовать cursor-pagination.
5. Версионирование «потом как-нибудь»
Ломающие изменения в API неизбежны.
Без версионирования вы просто ломаете клиентов.
Используйте, например:
/api/v1/...
О версионировании нужно думать с самого начала.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤13👍4
Ты сказал ИИ: «сделай систему уведомлений».
Он сделал через HTTP.
Пользователь каждые 2 секунды спрашивает сервер:
— «Есть ли уведомления?»
— «Есть ли уведомления?»
— «Есть ли уведомления?»
Это называется polling. Работает, но крайне неэффективно.
Если пользователей 1000, сервер получает 500 запросов в секунду. Все ответы: «Нет».
Правильный подход: WebSocket.
Соединение открывается один раз.
Когда приходит уведомление, сервер пушит его клиенту.
Пользователь ничего не спрашивает.
Разница такова:
Polling: «Пришёл пакет? Пришёл? Пришёл?»
WebSocket: «У двери звонок — когда приходит, звонит».
Для чата, живых уведомлений, мгновенных цен лучше думать о WebSocket.
ИИ по умолчанию пишет на HTTP.
Если скажешь «нужны живые обновления» — перейдёт на WebSocket.
Но если не уточнишь, он выберет самый простой путь.
👉 @BackendPortal
Он сделал через HTTP.
Пользователь каждые 2 секунды спрашивает сервер:
— «Есть ли уведомления?»
— «Есть ли уведомления?»
— «Есть ли уведомления?»
Это называется polling. Работает, но крайне неэффективно.
Если пользователей 1000, сервер получает 500 запросов в секунду. Все ответы: «Нет».
Правильный подход: WebSocket.
Соединение открывается один раз.
Когда приходит уведомление, сервер пушит его клиенту.
Пользователь ничего не спрашивает.
Разница такова:
Polling: «Пришёл пакет? Пришёл? Пришёл?»
WebSocket: «У двери звонок — когда приходит, звонит».
Для чата, живых уведомлений, мгновенных цен лучше думать о WebSocket.
ИИ по умолчанию пишет на HTTP.
Если скажешь «нужны живые обновления» — перейдёт на WebSocket.
Но если не уточнишь, он выберет самый простой путь.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤2
Запускать несколько проектов локально — тот ещё минус вайб
localhost:3000, localhost:3001, localhost:8080… где вообще какой?
Один конфликт портов, и вся локальная среда разваливается.
Portless от Vercel Labs решает это аккуратно.
Вместо номеров портов ты получаешь стабильные именованные URL:
http://myapp.localhost:1355
http://api.myapp.localhost:1355
http://docs.myapp.localhost:1355
Что это решает:
• конфликты портов между проектами
• утечки cookies и storage между приложениями на разных портах
• путаницу «какая вкладка к чему относится?» в монорепозиториях
• Git worktrees: каждая ветка автоматически получает собственный поддомен
Работает с Next.js, Vite, Express, Nuxt, React Router, Angular, Expo.
Есть и AI-аспект.
Кодовые агенты часто хардкодили порты и ошибались. Именованные URL означают, что агент всегда точно знает, куда обращаться.
3.8k звёзд.
v0.5.2.
Проект активно поддерживается командой Vercel Labs.
И всё.
https://github.com/vercel-labs/portless
👉 @BackendPortal
localhost:3000, localhost:3001, localhost:8080… где вообще какой?
Один конфликт портов, и вся локальная среда разваливается.
Portless от Vercel Labs решает это аккуратно.
Вместо номеров портов ты получаешь стабильные именованные URL:
http://myapp.localhost:1355
http://api.myapp.localhost:1355
http://docs.myapp.localhost:1355
Что это решает:
• конфликты портов между проектами
• утечки cookies и storage между приложениями на разных портах
• путаницу «какая вкладка к чему относится?» в монорепозиториях
• Git worktrees: каждая ветка автоматически получает собственный поддомен
Работает с Next.js, Vite, Express, Nuxt, React Router, Angular, Expo.
Есть и AI-аспект.
Кодовые агенты часто хардкодили порты и ошибались. Именованные URL означают, что агент всегда точно знает, куда обращаться.
3.8k звёзд.
v0.5.2.
Проект активно поддерживается командой Vercel Labs.
npm install -g portless
portless run next dev
И всё.
https://github.com/vercel-labs/portless
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
This media is not supported in your browser
VIEW IN TELEGRAM
Если это компилируется, то оно должно:
1. задеплоиться, и
2. запуститься .
Выше на демо: если я забуду предоставить Service, необходимый моей Lambda-функции (например, BucketEventSource), то получу ошибку типов.
Layers включают Resources и IAM-политики с минимально необходимыми правами (least-privilege). Корректность гарантирована.
👉 @BackendPortal
1. задеплоиться, и
2. запуститься .
Выше на демо: если я забуду предоставить Service, необходимый моей Lambda-функции (например, BucketEventSource), то получу ошибку типов.
Layers включают Resources и IAM-политики с минимально необходимыми правами (least-privilege). Корректность гарантирована.
Please open Telegram to view this post
VIEW IN TELEGRAM
.git/info/exclude — одна из моих любимых возможностей Git, но я постоянно удивляюсь, когда разговариваю с людьми, которые о ней никогда не слышали.
По сути, она позволяет игнорировать файлы так же, как через
Это особенно удобно, когда нужно временно игнорировать какие-то файлы, появившиеся во время дебага или локальной разработки.
👉 @BackendPortal
По сути, она позволяет игнорировать файлы так же, как через
.gitignore, но без изменения самого файла .gitignore.Это особенно удобно, когда нужно временно игнорировать какие-то файлы, появившиеся во время дебага или локальной разработки.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10❤1
Я только что нашел 100% открытый и полностью бесплатный заменитель Postman, который работает прямо в вашем браузере без необходимости установки.
Его название — Hoppscotch.
Без лишнего веса для десктопа. Без $14/месяц с пользователя. Без сбора данных.
HTTP, GraphQL, WebSocket, тестирование в реальном времени, генерация кодовых фрагментов и миграция из Postman в один клик. Включает десктопную версию и CLI.
100% Открытый исходный код. Лицензия MIT.
👉 @BackendPortal
Его название — Hoppscotch.
Без лишнего веса для десктопа. Без $14/месяц с пользователя. Без сбора данных.
HTTP, GraphQL, WebSocket, тестирование в реальном времени, генерация кодовых фрагментов и миграция из Postman в один клик. Включает десктопную версию и CLI.
100% Открытый исходный код. Лицензия MIT.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤15🤔2
Приглашаем вас на встречу Архитектурного клуба Яндекс 360!
Инженеры Яндекс 360 накопили большой опыт в проектировании систем, которыми пользуются более 100 миллионов человек каждый месяц, и теперь готовы делиться этим опытом и объединять вокруг него единомышленников.
26 марта в 17:00 Вместе с Дарьей Андреевой, руководителем бэкенд-разработки Биллинга и B2B‑платформы, мы разберём нетривиальную задачу по проектированию больших групп в организации на примере Яндекс 360.
Покажем не только архитектурные решения, но и практический подход к созданию высоконагруженных сервисов.
Нужно только оставить почту: ссылка.
Инженеры Яндекс 360 накопили большой опыт в проектировании систем, которыми пользуются более 100 миллионов человек каждый месяц, и теперь готовы делиться этим опытом и объединять вокруг него единомышленников.
26 марта в 17:00 Вместе с Дарьей Андреевой, руководителем бэкенд-разработки Биллинга и B2B‑платформы, мы разберём нетривиальную задачу по проектированию больших групп в организации на примере Яндекс 360.
Покажем не только архитектурные решения, но и практический подход к созданию высоконагруженных сервисов.
Нужно только оставить почту: ссылка.
Rate Limiting vs Throttling
Rate limiting = отклонение запросов после достижения лимита
Throttling = замедление обработки запросов вместо их отклонения
Пример:
Клиент отправляет 100 запросов/сек
Rate limiting
→ разрешить первые 50
→ остальные отклонить с ошибкой 429 Too Many Requests
Throttling
→ поставить запросы в очередь или задержать
→ обрабатывать их постепенно
Rate limiting — отбрасывает лишний трафик
Throttling — контролирует скорость обработки трафика
Оба подхода защищают систему от перегрузки.
Как это реализуют
Rate limiting → алгоритмы token bucket или sliding window counters
Throttling → очередь запросов + пул воркеров (контролируемая скорость обработки)
👉 @BackendPortal
Rate limiting = отклонение запросов после достижения лимита
Throttling = замедление обработки запросов вместо их отклонения
Пример:
Клиент отправляет 100 запросов/сек
Rate limiting
→ разрешить первые 50
→ остальные отклонить с ошибкой 429 Too Many Requests
Throttling
→ поставить запросы в очередь или задержать
→ обрабатывать их постепенно
Rate limiting — отбрасывает лишний трафик
Throttling — контролирует скорость обработки трафика
Оба подхода защищают систему от перегрузки.
Как это реализуют
Rate limiting → алгоритмы token bucket или sliding window counters
Throttling → очередь запросов + пул воркеров (контролируемая скорость обработки)
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8
Интересный факт: Stripe использует MongoDB для хранения своих основных данных, и при этом система обрабатывает 5 миллионов QPS и работает с 2000+ шардами
Некоторое время назад Stripe опубликовали инженерный блог, в котором рассказали о своей архитектуре баз данных и о том, как они масштабировали MongoDB-кластер, чтобы поддерживать нагрузку в 5 млн QPS, при этом сохраняя стабильность и управляемость системы.
В статье также подробно разбираются:
- платформа перемещения данных (data movement platform)
- логическое и физическое шардинг-разделение
- и, что особенно интересно, механизм “flip switch” — переключатель, позволяющий безопасно менять маршрутизацию или конфигурацию системы.
Всё это реализовано очень аккуратно и производит действительно сильное впечатление.
👉 @BackendPortal
Некоторое время назад Stripe опубликовали инженерный блог, в котором рассказали о своей архитектуре баз данных и о том, как они масштабировали MongoDB-кластер, чтобы поддерживать нагрузку в 5 млн QPS, при этом сохраняя стабильность и управляемость системы.
В статье также подробно разбираются:
- платформа перемещения данных (data movement platform)
- логическое и физическое шардинг-разделение
- и, что особенно интересно, механизм “flip switch” — переключатель, позволяющий безопасно менять маршрутизацию или конфигурацию системы.
Всё это реализовано очень аккуратно и производит действительно сильное впечатление.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥3💊1
Топ-ресурсы для изучения backend и системного программирования:
▪️ OSDev Wiki
▪️ Beej's Guides to Network Programming
▪️ Julia Evans' Blog
▪️ Low Level Programming University
▪️ Computer Science from the Bottom Up
▪️ Crafting Interpreters
▪️ The Linux Documentation Project
▪️ Writing an OS in Rust
▪️ Destroy All Software
▪️ Курсы Casey Muratori
▪️ MIT OpenCourseWare
▪️ Compiler Explorer
▪️ Computer Systems: A Programmer's Perspective
▪️ Hacker News
▪️ Lobsters
▪️ /r/systems
▪️ ByteByteGo
▪️ High Scalability
▪️ Martin Kleppmann's Blog
▪️ Architecture Notes
▪️ The Morning Paper
▪️ Brendan Gregg's Blog
▪️ Dan Luu's Blog
▪️ Phil Eaton's Blog
▪️ Database Internals
▪️ Designing Data‑Intensive Applications
▪️ Systems We Love
▪️ Strange Loop Conference (видеозаписи)
▪️ Papers We Love
▪️ CMU Database Group
👉 @BackendPortal
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9
Большинство разработчиков используют Spring каждый день… но многие до сих пор не до конца понимают AOP
Давайте разберёмся.
Что такое AOP?
AOP — это способ добавлять общий (cross-cutting) функционал без изменения основного бизнес-кода.
Примеры cross-cutting логики:
- логирование (Logging)
- проверки безопасности (Security checks)
- транзакции (Transactions)
- кэширование (Caching)
- отслеживание производительности (Performance tracking)
- обработка ошибок (Error handling)
Такой функционал нужен почти везде, но он не должен загромождать бизнес-логику.
Зачем нужен AOP?
Без AOP:
одна и та же логика повторяется во множестве методов.
С AOP:
вы пишете эту логику один раз и применяете ко всем нужным местам.
Плюсы:
- чистый код
- повторное использование
- отсутствие вмешательства в бизнес-логику (non-intrusive)
Как AOP работает в Spring
В Spring создаётся proxy (объект-обёртка) вокруг вашего bean.
Этот proxy решает:
- нужно ли запускать аспектную логику
- когда её запускать
- вокруг каких методов её применять
Вы продолжаете вызывать тот же самый bean, но Spring незаметно оборачивает его proxy-объектом.
Где AOP используется в реальных проектах
-
-
-
- Spring Security
- системы логирования
- аудит (Auditing)
- rate limiting
- таймеры производительности
Практически каждый серьёзный проект на Spring Boot использует AOP “под капотом”.
👉 @BackendPortal
Давайте разберёмся.
Что такое AOP?
AOP — это способ добавлять общий (cross-cutting) функционал без изменения основного бизнес-кода.
Примеры cross-cutting логики:
- логирование (Logging)
- проверки безопасности (Security checks)
- транзакции (Transactions)
- кэширование (Caching)
- отслеживание производительности (Performance tracking)
- обработка ошибок (Error handling)
Такой функционал нужен почти везде, но он не должен загромождать бизнес-логику.
Зачем нужен AOP?
Без AOP:
одна и та же логика повторяется во множестве методов.
С AOP:
вы пишете эту логику один раз и применяете ко всем нужным местам.
Плюсы:
- чистый код
- повторное использование
- отсутствие вмешательства в бизнес-логику (non-intrusive)
Как AOP работает в Spring
В Spring создаётся proxy (объект-обёртка) вокруг вашего bean.
Этот proxy решает:
- нужно ли запускать аспектную логику
- когда её запускать
- вокруг каких методов её применять
Вы продолжаете вызывать тот же самый bean, но Spring незаметно оборачивает его proxy-объектом.
Где AOP используется в реальных проектах
-
@Transactional — транзакционный AOP-
@Cacheable — AOP для кэширования-
@Async — асинхронный AOP- Spring Security
- системы логирования
- аудит (Auditing)
- rate limiting
- таймеры производительности
Практически каждый серьёзный проект на Spring Boot использует AOP “под капотом”.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Недавний вопрос с code review на собеседовании по Java: что не так с этим сервисом?
Код компилируется, тесты проходят (green), но в production всё ломается.
[Дано]
Сервис обрабатывает запросы на вывод средств. Требования простые:
- нельзя вывести больше, чем есть на балансе;
- нельзя создать два запроса одновременно.
(код на прикреплённом изображении)
[Задача]
Два запроса от одного пользователя пришли одновременно. В результате баланс ушёл в минус, и было создано два запроса.
[Объясните]
- точную последовательность событий при конкурентных запросах;
- спасёт ли ситуацию аннотация
- как правильно исправить эту проблему.
👉 @BackendPortal
@Service
@RequiredArgsConstructor
public class СервисВывода {
private final РепозиторийАккаунтов accountRepository;
private final РепозиторийВыводов withdrawalRepository;
public void запросВывода(Long userId, BigDecimal amount) {
Account account =
accountRepository.findByUserId(userId)
.orElseThrow();
if (account.getBalance().compareTo(amount) < 0) {
throw new ИсключениеНедостаточноСредств();
}
boolean hasPending = withdrawalRepository
.existsByUserIdAndStatus(uid, Status.PENDING);
if (hasPending) {
throw new ИсключениеВыводУжеВОбработке();
}
account.setBalance(account.getBalance().subtract(amount));
accountRepository.save(account);
withdrawalRepository.save(
new Withdrawal(uid, amount, Status.PENDING)
);
}
}
Код компилируется, тесты проходят (green), но в production всё ломается.
[Дано]
Сервис обрабатывает запросы на вывод средств. Требования простые:
- нельзя вывести больше, чем есть на балансе;
- нельзя создать два запроса одновременно.
(код на прикреплённом изображении)
[Задача]
Два запроса от одного пользователя пришли одновременно. В результате баланс ушёл в минус, и было создано два запроса.
[Объясните]
- точную последовательность событий при конкурентных запросах;
- спасёт ли ситуацию аннотация
@Transactional над методом или нет? Почему?- как правильно исправить эту проблему.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Разработчики на Go знают эту боль:
Dingo пробует кое-что интересное.
Мета-язык, который компилируется в чистый Go, но добавляет такие вещи, как:
• типы Result
• сопоставление с образцом (pattern matching)
• распространение ошибок через
Пишешь на современном синтаксисе → на выходе получаешь чистый Go.
👉 @BackendPortal
if err != nil
if err != nil
if err != nil
Dingo пробует кое-что интересное.
Мета-язык, который компилируется в чистый Go, но добавляет такие вещи, как:
• типы Result
• сопоставление с образцом (pattern matching)
• распространение ошибок через
?Пишешь на современном синтаксисе → на выходе получаешь чистый Go.
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6❤2
Алгоритм Sliding Window Log в основном используется для rate limiting в системе. Он использует логи (журнал временных меток), чтобы проверять и разрешать запросы от пользователей.
Как это работает?
Алгоритм сохраняет временные метки запросов и постоянно проверяет их, удаляя те, которые вышли за пределы заданного временного окна.
Например, представим окно 5 секунд, и разрешено не более 5 запросов за 5 секунд.
Сервер принимает запросы в текущем окне. Если количество запросов меньше или равно 5, сервер их обрабатывает.
Когда мы переходим к 6-й секунде, удаляется временная метка запроса, который был получен на 1-й секунде. После этого сервер может принять новый запрос, полученный на 6-й секунде.
Таким образом, скользящее окно (sliding window) постоянно сдвигается вперёд секунда за секундой, удаляя временные метки старых запросов, которые выходят за пределы окна.
Алгоритм также обрабатывает краевые случаи (edge cases). Например, если в какой-то момент приходит 8 запросов, а лимит составляет 5 запросов за 5 секунд, лишние запросы будут отклонены. На следующей секунде сервер снова сможет принимать запросы, если после удаления устаревших временных меток появится свободное место в окне.
На практике через окно может проходить гораздо больше запросов. Например, можно задать окно 10 секунд с лимитом 1000 запросов. Такой подход позволяет обрабатывать всплески (bursts) запросов и при этом продолжать работу без остановки.
Мне потребовалось некоторое время, чтобы разобраться в этом алгоритме, но в итоге стало понятно.
Следующий и последний алгоритм для rate limiting — это Sliding Window Counter.
👉 @BackendPortal
Как это работает?
Алгоритм сохраняет временные метки запросов и постоянно проверяет их, удаляя те, которые вышли за пределы заданного временного окна.
Например, представим окно 5 секунд, и разрешено не более 5 запросов за 5 секунд.
Сервер принимает запросы в текущем окне. Если количество запросов меньше или равно 5, сервер их обрабатывает.
Когда мы переходим к 6-й секунде, удаляется временная метка запроса, который был получен на 1-й секунде. После этого сервер может принять новый запрос, полученный на 6-й секунде.
Таким образом, скользящее окно (sliding window) постоянно сдвигается вперёд секунда за секундой, удаляя временные метки старых запросов, которые выходят за пределы окна.
Алгоритм также обрабатывает краевые случаи (edge cases). Например, если в какой-то момент приходит 8 запросов, а лимит составляет 5 запросов за 5 секунд, лишние запросы будут отклонены. На следующей секунде сервер снова сможет принимать запросы, если после удаления устаревших временных меток появится свободное место в окне.
На практике через окно может проходить гораздо больше запросов. Например, можно задать окно 10 секунд с лимитом 1000 запросов. Такой подход позволяет обрабатывать всплески (bursts) запросов и при этом продолжать работу без остановки.
Мне потребовалось некоторое время, чтобы разобраться в этом алгоритме, но в итоге стало понятно.
Следующий и последний алгоритм для rate limiting — это Sliding Window Counter.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6
Бэкенд-разработчики, это для вас:
Сценарий:
У вашей e-commerce платформы миллионы заказов. Команда маркетинга хочет видеть все завершённые заказы за последние 24 часа на дашборде.
Вопрос:
Почему такой запрос может работать медленно, и какие стратегии могут улучшить производительность?
👉 @BackendPortal
Сценарий:
У вашей e-commerce платформы миллионы заказов. Команда маркетинга хочет видеть все завершённые заказы за последние 24 часа на дашборде.
SELECT o.id, o.user_id, o.total, o.status
FROM orders o
WHERE o.status = 'completed'
AND o.created_at >= NOW() - INTERVAL '1 day';
Вопрос:
Почему такой запрос может работать медленно, и какие стратегии могут улучшить производительность?
Please open Telegram to view this post
VIEW IN TELEGRAM
Каждая масштабируемая система начинается с одного важного компонента: балансировщика нагрузки (Load Balancer).
Без него ваш backend рано или поздно начнёт падать под нагрузкой.
Вот как на самом деле работают балансировщики нагрузки.
1. Один сервер
Представим, что в системе есть один backend-сервер.
Весь трафик идёт на одну машину.
Users → Server
Когда трафик растёт:
- загрузка CPU увеличивается
- память заполняется
- latency растёт
В итоге сервер падает.
2. Решение — горизонтальное масштабирование
Вместо одного сервера запускается несколько серверов.
- Server 1
- Server 2
- Server 3
- Server 4
Но теперь нужен способ распределять запросы между ними.
Именно для этого используется Load Balancer.
3. Новая архитектура
Теперь схема выглядит так:
Users → Load Balancer → Multiple Servers
Балансировщик решает, какой сервер будет обрабатывать каждый запрос.
4. Популярные алгоритмы балансировки
Round Robin
Запросы распределяются по очереди.
Req1 → Server1
Req2 → Server2
Req3 → Server3
Простой и очень распространённый метод.
Least Connections
Трафик отправляется на сервер с наименьшим количеством активных соединений.
Полезно, когда время обработки запросов сильно различается.
IP Hash
Запросы от одного IP-адреса пользователя направляются на один и тот же сервер.
Часто используется, когда нужна session stickiness.
5. Дополнительные функции балансировщиков
Балансировщики также обеспечивают:
- health checks
- failover
- SSL termination
- routing трафика
Если сервер становится нездоровым, он автоматически исключается из пула.
Пользователи этого даже не замечают.
6. Популярные балансировщики в продакшене
- Nginx
- HAProxy
- AWS Elastic Load Balancing (ELB / ALB)
- Cloudflare
Балансировщик нагрузки — это первый шаг к масштабированию backend-системы.
👉 @BackendPortal
Без него ваш backend рано или поздно начнёт падать под нагрузкой.
Вот как на самом деле работают балансировщики нагрузки.
1. Один сервер
Представим, что в системе есть один backend-сервер.
Весь трафик идёт на одну машину.
Users → Server
Когда трафик растёт:
- загрузка CPU увеличивается
- память заполняется
- latency растёт
В итоге сервер падает.
2. Решение — горизонтальное масштабирование
Вместо одного сервера запускается несколько серверов.
- Server 1
- Server 2
- Server 3
- Server 4
Но теперь нужен способ распределять запросы между ними.
Именно для этого используется Load Balancer.
3. Новая архитектура
Теперь схема выглядит так:
Users → Load Balancer → Multiple Servers
Балансировщик решает, какой сервер будет обрабатывать каждый запрос.
4. Популярные алгоритмы балансировки
Round Robin
Запросы распределяются по очереди.
Req1 → Server1
Req2 → Server2
Req3 → Server3
Простой и очень распространённый метод.
Least Connections
Трафик отправляется на сервер с наименьшим количеством активных соединений.
Полезно, когда время обработки запросов сильно различается.
IP Hash
Запросы от одного IP-адреса пользователя направляются на один и тот же сервер.
Часто используется, когда нужна session stickiness.
5. Дополнительные функции балансировщиков
Балансировщики также обеспечивают:
- health checks
- failover
- SSL termination
- routing трафика
Если сервер становится нездоровым, он автоматически исключается из пула.
Пользователи этого даже не замечают.
6. Популярные балансировщики в продакшене
- Nginx
- HAProxy
- AWS Elastic Load Balancing (ELB / ALB)
- Cloudflare
Балансировщик нагрузки — это первый шаг к масштабированию backend-системы.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5❤3👍3
This media is not supported in your browser
VIEW IN TELEGRAM
Как работает Depth-First Search (DFS):
1. Начинаем со стека: помещаем исходную вершину в стек и помечаем её как посещённую.
2. Извлекаем верхнюю вершину: берём элемент с вершины стека — это текущая вершина для обхода.
3. Обрабатываем вершину: выполняем нужное действие — выводим, проверяем условие, сохраняем путь и т.д.
4. Добавляем непосещённых соседей: просматриваем всех соседей текущей вершины. Для каждого непосещённого — помечаем как посещённый и кладём в стек.
5. Повторяем, пока стек не пуст: возвращаемся к шагу 2. На каждой итерации уходим глубже по одному из путей перед возвратом назад.
6. Бэктрекинг происходит автоматически: если у вершины нет непосещённых соседей, ничего не добавляется в стек, и следующий
👉 @BackendPortal
1. Начинаем со стека: помещаем исходную вершину в стек и помечаем её как посещённую.
2. Извлекаем верхнюю вершину: берём элемент с вершины стека — это текущая вершина для обхода.
3. Обрабатываем вершину: выполняем нужное действие — выводим, проверяем условие, сохраняем путь и т.д.
4. Добавляем непосещённых соседей: просматриваем всех соседей текущей вершины. Для каждого непосещённого — помечаем как посещённый и кладём в стек.
5. Повторяем, пока стек не пуст: возвращаемся к шагу 2. На каждой итерации уходим глубже по одному из путей перед возвратом назад.
6. Бэктрекинг происходит автоматически: если у вершины нет непосещённых соседей, ничего не добавляется в стек, и следующий
pop возвращает нас назад по пути.Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Хотите разобраться с разработкой веб-приложений на Go?
Let's Go — это понятное и лаконичное руководство, которое охватывает всё необходимое: лучшие практики, структуру проекта и практические паттерны кода — включая управление зависимостями, аутентификацию, работу с базами данных, тестирование и многое другое.
👉 @BackendPortal
Let's Go — это понятное и лаконичное руководство, которое охватывает всё необходимое: лучшие практики, структуру проекта и практические паттерны кода — включая управление зависимостями, аутентификацию, работу с базами данных, тестирование и многое другое.
Please open Telegram to view this post
VIEW IN TELEGRAM
lets-go.alexedwards.net
Let’s Go! Learn to build web apps with Go
A clear and concise guide to practical code patterns, project organization, best practices and more.
❤3