backendportal | Unsorted

Telegram-канал backendportal - Backend Portal | Программирование

15708

Присоединяйтесь к нашему каналу и погрузитесь в мир Backend-разработки Связь: @devmangx РКН: https://clck.ru/3FobxK

Subscribe to a channel

Backend Portal | Программирование

Этот трюк с GitHub PR надо знать

Просто добавь “0” перед словом “github” в URL любого Pull Request, и у тебя откроется полноценный PR-вьювер, который подсвечивает каждую строку diff’а цветом в зависимости от того, сколько внимания от человека она, скорее всего, требует.

Он ищет не только баги. Он подсвечивает всё, что заслуживает второго взгляда: захардкоженные секреты, странные крипторежимы, подозрительную логику или грязный код.

Очень полезный способ быстрее проводить code review и находить то, что обычно легко пропустить.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Раньше у GitHub была монолитная база данных, которая держала 950 000 транзакций в секунду 🤯

Но по мере роста компании эта база превратилась в... сами понимаете что. Логичное решение = развалить монолит на несколько меньших баз. На деле все оказалось гораздо сложнее, чем они думали.

Я как раз нашёл видео, где разбирают весь их процесс: какие шаги они предпринимали, как сделали миграцию без даунтайма и при этом ничего не сломали в существующем функционале.

После просмотра ты поймешь, как в реальных проектах мигрируют базы без простоя, как подходить к таким сложным задачам по шагам, и получишь живой пример того, с какими проблемами сталкиваются при масштабировании баз данных и как их решают.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Уроки по ИБ, белый хакинг, вирусы, социальная инженерия, безопасность

ИБ Книга
Более 1660 русскоязычных книг по ИБ и Социальной Инженерии можно найти на канале.

no system is safe // cybersec — один из древнейших ресурсов по информационной безопасности в рунете. Книги, курсы, полезные тулсы, уроки по Linux, новости клирнета и даркнета.

Python и 1000 программ уроки по Python. Python мы будем использовать для создания хакерского софта.

Этичный Хакер — один из крупнейших ресурсов по информационной безопасности в СНГ.

Бэкап — канал с исходниками популярных проектов. Здесь вы найдёте исходные коды нейросетей, ботов, сайтов и других интересных проектов, которые дадут дополнительные знания

Весь материал на каналах в общем доступе. Ничего лишнего.

Читать полностью…

Backend Portal | Программирование

Тебя спрашивают на бэкенд-собесе.

Вопрос:

Как бы ты спроектировал распределенную систему cron-планирования, которая гарантирует, что задачи будут запускаться ровно один раз, вовремя, на нескольких нодах, без коллизий и дубликатов?


Как к этому подойти:

Начни с базовых требований:

• централизованно определять и хранить расписания
• несколько scheduler-нод, но в конкретный момент только одна должна триггерить задачу
• задачи должны выполняться ровно один раз, даже если ноды рестартуют или падают
• поддержка ретраев, backoff и идемпотентных обработчиков
• видимость last-run и next-run

Архитектура системы:

• Control Plane: UI/API для создания cron-задач
• кластер scheduler-ов
• распределенный локинг (Redis, Zookeeper, Etcd, DynamoDB)
• пул воркеров, который выполняет задачи
• хранилище результатов и метаданных

Гарантия, что задачу триггерит только одна нода:

• на каждую задачу используется отдельный распределенный лок
• нода, которая захватывает лок, и запускает выполнение
• у лока есть TTL, чтобы не виснуть навечно
• если нода умерла, другая подберет задачу на следующем тике

Как работает планирование:

• все scheduler-ноды подгружают cron-описания
• каждую секунду каждая нода проверяет, что надо запускать
• если задача должна стартовать, нода пробует взять лок
• победитель отправляет задачу в пул воркеров

Ретраи и ошибки:

• у каждой задачи свои правила ретраев (число попыток и backoff)
• при ошибке создается событие retry
• ретраи тоже проходят через тот же механизм локов
• воркер должен быть идемпотентным, чтобы переживать редкие дубликаты

Масштабирование воркеров:

• воркеры должны быть stateless и масштабироваться горизонтально
• задачи — это сообщения с job ID и payload
• используется очередь/брокер (Kafka, SQS, RabbitMQ)
• планирование отделено от выполнения

Консистентность и надежность:

• cron-определения хранятся в консистентной базе
• scheduler-ноды держат копии в памяти и периодически обновляют
• сохраняется история запусков (start, end, статус, ошибка)
• можно включить catch-up для пропущенных запусков

Обсервабилити:

• метрики next_run_at, last_run_at, длительность, успех/ошибка
• Prometheus-метрики и трассировка медленных задач
• алерты на зависшие задачи и повторные фейлы
• UI с инфой, какая нода выполняла какой запуск

Как ответить на собесе:

Я бы построил распределенный cron с централизованным управлением расписаниями, несколькими scheduler-нодами и распределенным локом, чтобы задача триггерилась ровно один раз. Выполнение вынесено в пул воркеров, каждый запуск логируется, ретраи координируются через очередь, и система остаётся консистентной даже при падении нод.


👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Оказалось, что контейнеры внутри одного Cloud Run инстанса могут общаться по локалке. Например через http://localhost:5000

Если задать контейнерам имена (например sidecar), то можно обращаться уже так: http://sidecar:5000

Полезно, когда нужно подключить sidecar-сервис или поделить задачи между контейнерами.

Репо с примером:
https://github.com/steren/cloud-run-multi-container-communication

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Крупные компании вроде Reddit перенесли бэкенд комментариев с Python на Go и в результате срезали критическую задержку почти вдвое.

Это хорошо показывает типичный выбор для команд разработки:

Python — быстрее в разработке (прототипы, богатая экосистема библиотек)

Go — быстрее в продакшене (низкая задержка, отлично держит высокую нагрузку)

Кому хочется выучить Go через практику и реальные проекты — можно глянуть это

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Когда готовишься к собесам в FAANG или просто техинтервью, обычно нужно решать тонну задач.
Но фишка в том, что не надо запоминать все решения.

Важно другое — научиться узнавать паттерны. 💊

Вот 25 основных паттернов, которые реально помогают проходить собеседования спокойно и без паники.

Базовые паттерны для массивов и поиска

1. Two Pointers — когда массив отсортирован или нужно найти пару элементов.
2. Sliding Window — задачи на подстроки и непрерывные подмассивы.
3. Prefix Sum — быстрый подсчет суммы диапазонов.
4. Merge Intervals — работа с пересекающимися интервалами.
5. Binary Search — всё, что касается поиска в отсортированных данных.

Сортировка, рекурсия и связанные списки

6. Sorting-Based — сортировка перед анализом данных.
7. Fast and Slow Pointers — поиск середины или цикла в связном списке.
8. Backtracking — генерация комбинаций, перестановок, рекурсивные обходы.
9. Divide and Conquer — разбиение задачи на подзадачи и объединение результата.
10. Linked List Tricks — разворот списка, удаление узлов, двойные указатели.

Стек, очередь и хеш-структуры

11. Stacks & Queues — задачи на LIFO/FIFO.
12. Monotonic Stack — поиск следующего большего или меньшего элемента.
13. Expression Evaluation — парсинг выражений, калькуляторы, скобки.
14. String Manipulation — палиндромы, анаграммы, работа со строками.
15. Hashmaps — быстрые lookup, подсчеты частот.

Деревья, кучи и продвинутые структуры

16. Binary Trees & BST — обходы, баланс, минимумы, максимумы.
17. Path Sum — поиск валидных путей или сумм в деревьях.
18. K-th Largest (Heaps) — получение k-го по величине элемента.
19. Top-K Frequent — задачи на частотность.
20. Merge K Sorted Lists/Arrays — объединение нескольких отсортированных потоков.

Алгоритмы и системное мышление

21. Dynamic Programming — оптимизация и задачи с пересекающимися подзадачами.
22. Greedy — локально оптимальные шаги для финального результата.
23. Graph Traversal — BFS/DFS, обходы, проверка связности.
24. Graph Algorithms — кратчайший путь, стоимость, маршруты.
25. Design Problems — структуры вроде LRU Cache, Rate Limiter, Trie и т.п.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Вот небольшая анимация, которая показывает, как циклы искажают связь между исходным кодом и реально выполняемыми инструкциями. Думаю, новичкам это часто сложно понять, но по моему мнению, умение делать такие выводы — один из ключевых шагов к тому, чтобы научиться действительно хорошо читать код.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Так что я, как обычно, копался в Docker и узнал, насколько круто у него работает сеть.

Когда создаешь контейнер, он по умолчанию использует bridge-сеть, и контейнер получает приватный IP через встроенный IPAM (IP Address Management) драйвер автоматически.

Но можно создать свою кастомную bridge-сеть (user-defined network), и тогда контейнеры смогут общаться по имени, если они в одной сети. В дефолтной bridge-сети контейнеры могут общаться только по IP.

Я попробовал собрать простую небольшую продакшн-эмуляцию, чтобы лучше разобраться. Там четыре контейнера: API-сервер, веб-фронтенд, база данных и reverse-proxy. И три bridge-сети: database, backend и frontend.

API-сервер подключен к database и backend сетям, а nginx-proxy подключен к frontend и backend, потому что ему нужно прокидывать трафик между портами. Контейнеры в одной сети могут пинговать друг друга, остальные — нет, пока ты явно не подключишь их к нужным сетям.

Сеть database изолирована и без доступа в интернет с флагом --internal. Это удобный способ защитить базу. Контейнеры внутри этой сети могут общаться друг с другом, но доступа наружу у них нет.

Остальные контейнеры получают доступ в интернет классическим способом - у каждого свой приватный IP, и они подключены к docker0 через veth-пары (виртуальные Ethernet-интерфейсы). docker0 работает как виртуальный свитч, который отвечает за маршрутизацию трафика между контейнерами и сетью хоста. Это выглядит круто, потому что фактически имитирует интернет в миниатюре, только вместо физических устройств тут контейнеры.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

TLS termination звучит просто, но это один из ключевых элементов современной инфраструктуры.

Вместо того, чтобы каждый бэкенд сам занимался шифрованием и расшифровкой, всю TLS-нагрузку берет на себя балансировщик на границе сети.

Когда клиент подключается, TLS-handshake происходит между браузером и балансировщиком. Балансировщик использует свой сертификат, устанавливает защищенный канал и расшифровывает входящий HTTPS-трафик.

Дальше он общается с бэкендами уже по обычному HTTP внутри приватной сети.

В результате сервера приложений не тратят CPU на криптографию, им не нужны сертификаты, и они занимаются только бизнес-логикой.

Плюс обновление сертификатов становится проще — все лежит в одном месте, а не разбросано по десятку сервисов.

Важно помнить:

незашифрованный трафик живет только внутри доверенной внутренней сети. Снаружи все остается зашифрованным до самого балансировщика.


Чистый, удобный и очень распространенный подход, который помогает держать баланс между безопасностью и производительностью.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Короткая заметка про k8s:

Оказалось, что можно настраивать лимиты пропускной способности для пода или деплоймента. По умолчанию эта фича отключена. Но входящий и исходящий трафик можно контролировать через аннотации на поде, примерно так 😃

Кстати: M это Mbps, G это Gbps.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Одна простая привычка, которая сильно упрощает поддержку Dockerfile, это сортировка многострочных списков пакетов по алфавиту.

На первый взгляд мелочь, но влияние на читаемость и будущую поддержку заметное.

Когда ставишь пакеты в многострочном apt-get install или apk add блоке, легко случайно добавить дубликат или пропустить что-то, что затерялось в середине списка.

Алфавитная сортировка полностью снимает этот вопрос. Список можно быстро просканировать, сразу увидеть дубли и держать всё в едином стиле на разных окружениях.

Плюс уменьшаются шумные диффы в код-ревью.

Когда пакеты отсортированы, добавление или удаление одного пункта выглядит как аккуратное и предсказуемое изменение.

Без сортировки маленькое обновление часто превращается в огромный diff, и ревью становится сложнее, чем должно быть.

Этот подход особенно полезен, когда команда растёт.

Несколько человек, трогающих один Dockerfile, не начинают перетасовывать строки под свой вкус или форматировать по-разному.

Структура остаётся стабильной, и поддержка со временем становится проще.
Небольшое улучшение, но на сотнях билдов оно экономит заметно нервов и времени.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

💧 А вы заметили, насколько сейчас сложнее устроиться на работу?

Да даже получать приглашение на техническое собеседование.

К примеру, на хх.ру при нормальном резюме после 100 откликов — ты должен получить минимум 4 приглашения от эйчар.

Если у вас меньше, то тут что-то не чисто.

И это я говорю, если мы будем откликаться на позицию мидл и сеньор, т.к. на джунов вакансий кратно меньше.

Один мой знакомый недавно проводил эксперимент на эту тему:

Он выложил вакансии на 3 разные позиции и посмотрел на всё это дело глазами HR, разобрал резюме кандидатов, а затем выложил ролик на свой ют канал.

Его зовут Вадим Новоселов - один из немногих, кто показывает рынок трудоустройства в IT изнутри.

В тг канале много авторского контента:

(тут) можно оставить своё резюме для прожарки на предстоящем стриме

(тут) гайд по трудоустройству за 3-4 месяца

(тут) подкаст о том, что будет с рынком айти в рф

Этот человек вкладывает душу в свой контент и проекты, советую подписаться и черпать для себя полезные фишки: @gernar288

Читать полностью…

Backend Portal | Программирование

Совет: всегда добавляй workflow_dispatch в триггеры workflow.

Так у тебя появится кнопка в UI GitHub, чтобы вручную запускать новые прогонки (когда CI, как обычно, развалится).

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Сообщество разработчиков объявило о выходе экспериментального CRDT-расширения для Postgres. Проект открыт и доступен для изучения и использования.

CRDT это тип данных, который применяется в приложениях с одновременным редактированием. Простой пример — Google Docs, где несколько пользователей могут печатать одновременно, а изменения автоматически объединяются без конфликтов.

Обычно такие структуры сериализуются на стороне сервера и только потом сохраняются в базу. Новое расширение меняет подход: теперь Postgres может работать с CRDT нативно — хранить, индексировать, искать и автоматически объединять изменения прямо в базе данных.

Авторы проекта показывают, как это может выглядеть в будущем:

create table blog_posts (
id uuid primary key,
title text,
body crdt default '{}'
);


Идея в том, чтобы отправлять только diff изменений, а база уже сама разрулит конфликты, вместо того чтобы перезаписывать данные.

Также предполагается поддержка WebSockets для быстрого обмена изменениями между клиентами и последующей отправки батчей в Postgres.

Проект может стать важным шагом для приложений реального времени, совместного редактирования контента и распределённых систем.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Когда между идеей и продом — преград нет!


В VK любят решать сложные и масштабные задачи, а ещё — быстро реализовывать идеи. Компания рассказала, каких принципов придерживается команда в работе и какими результатами гордится. Переходите по ссылке, там много интересного!

Читать полностью…

Backend Portal | Программирование

Когда приложению нужно узнать о чем-то важном, например что пользователь оплатил подписку, у тебя есть два варианта:

1. приложение дергает API раз в пять минут, проверяя, был ли новый платеж;
2. платежная система сама шлет тебе уведомление в момент события.

Первый вариант — это polling: ты спрашиваешь, даже если ничего не произошло. Работает, но медленно и плохо масштабируется.

Второй вариант — webhook: HTTP-коллбек, который срабатывает, когда произошло событие.

Вместо того чтобы опрашивать систему, она сама присылает нужные данные.

Как выглядит поток, если ты используешь вебхук:

1. настраиваешь публичный эндпоинт;
2. твой сервер принимает POST с данными платежа;
3. проверяешь подпись (секретный ключ);
4. выполняешь свою бизнес-логику (платеж подтвержден, подписка активна и так далее).

Типичные проблемы:

- платеж может прийти дважды, поэтому сохраняют обработанные ID (идемпотентность);
- события могут прийти не по порядку, так что на хронологию лучше не рассчитывать;
- запрос может отправить кто угодно, поэтому обязательна проверка подписи.

Вебхуки важны потому, что избавляют приложение от постоянного опроса сторонней системы.

Сегодня их используют везде: платежи, подписки, деплои, интеграции, автоматизации и вообще любые сценарии, где другой сервис узнает о событии раньше тебя.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Большинство людей используют grep чтобы искать по файлам. Я использую его чтобы выживать в продовых пожарах в 3 ночи.

grep "error" logfile.txt
→ Ищет "error" в файле.

grep -i "error" logfile.txt
→ Ищет без учета регистра.

grep -r "TODO" /project/
→ Рекурсивный поиск по директориям.

grep -n "function" script.py
→ Показывает номер строки вместе с результатами.

grep -v "debug" logfile.txt
→ Показывает всё, кроме строк с "debug".

grep -c "warning" logfile.txt
→ Считает количество совпадений.

grep -w "cat" animals.txt
→ Совпадение только по целым словам.

grep -C 3 "exception" logfile.txt
→ Показывает 3 строки до и после совпадения.

grep "import" *.py
→ Ищет сразу по нескольким файлам.

grep -E "error|warning|critical" logfile
→ Ищет по нескольким шаблонам сразу.

Тот самый продовый пожар в 3 ночи
Приложение упало. Пользователи бесятся. Телефон разрывается.

grep -rni "exception" /var/log/ | grep "2025-12-02"
Это находит все исключения в логах за сегодня. С номерами строк. По всем файлам.

Тысячи строк сужаются до причины падения за секунды.

Почему это важно
Твой IDE не работает на удалённых серверах. Не тянет гигабайтные логи. И точно не помогает в 3 ночи, когда прод лег.

А grep помогает.

Разница между джуном и сеньором?
Умение пользоваться терминалом, когда это реально нужно.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Большинство инженерных команд косячат с архитектурой сообщений, потому что не понимают простую вещь:

Стримы хранят правду.
Очереди выполняют работу.

Когда это путают, система начинает кровоточить.

Я видел проекты, где слили миллионы просто потому, что всё пихали в очередь типа

"Ну просто запушим заказ в очередь, а там обработаем!"


У большинства очередей сообщения удаляются после обработки.
Никакой истории, никакого рефлоу, никакого аудита.
Только pain и гадания.

С другой стороны есть команды, которые влюбляются в Kafka:
"Мы будем стримить абсолютно всё!"


Запомни правило, которое мне самому хотелось услышать раньше:

Если событие меняет состояние бизнеса → стрим.
Если сообщение это действие к выполнению → очередь.


Стримы: OrderPlaced, PaymentAuthorized, InventoryReserved
Это факты.
Они должны быть долговечные, воспроизводимые, упорядоченные и поддающиеся аудиту.

Очереди: SendEmail, CapturePayment, GenerateInvoice
Это задачи, которые имеют срок годности.
Они важны сейчас, а не через полгода.

Событие попадает в стрим → воркеры генерируют задачи → очереди выполняют их.

Сначала — регистр (ledger).
Потом — конвейер.

Всё остальное технический долг, который выглядит "умно" только на бумаге.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Оптимизация слоев Docker-образа сократила время деплоя с 12 минут до 90 секунд.

Изначальный Dockerfile:

Любое изменение кода пересобирало весь образ
Зависимости ставились каждый раз заново
Кэш слоев никак не использовался

Размер образа был 1.2GB

Проблемный фрагмент:

COPY . /app
RUN pip install -r requirements.txt


Что было не так:

Любое изменение в проекте инвалидировало слой с pip install
Пакеты скачивались заново при каждом билде
CI/CD страдал по полной

Правка:

COPY requirements.txt /app/
RUN pip install -r requirements.txt
COPY . /app


Дополнительные улучшения:

Мульти-стейдж билды для уменьшения итогового размера

.dockerignore для мусора, который не должен попадать в образ

Базовый образ Alpine, где это уместно

Грамотный caching в CI/CD

Результат:

Время сборки: 12 минут → 90 секунд (ускорение на 87%)
Размер образа: 1.2GB → 340MB
Трафик в Docker Hub: минус 60%
Продуктивность команды: заметно выросла

Кэшируй то, что меняется редко. Копируй то, что меняется часто, в самом конце.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Уменьшаем время выборки из БД с 2–3 секунд до ~100 мс:

SELECT * FROM transactions
WHERE user_id = 40
ORDER BY created_at DESC
LIMIT 20 OFFSET 10000;


На первый взгляд запрос нормальный?
ДА, вроде ок.

Но:

- это OFFSET-пагинация
- и это прям ПЛОХО
- БД вытягивает 10020 строк и выкидывает 10000, чтобы показать 20, лол
- чем больше OFFSET, тем больше нагрузка на БД
- со временем запрос начинает занимать больше 2 секунд, пока растет объем данных

Решение:

KEYSET (seek) пагинация: добавляем условие вида created_at < last_seen_timestamp

SELECT * FROM transactions
WHERE user_id = 40
AND created_at < '2024-05-01 10:00:00'
ORDER BY created_at DESC
LIMIT 20;


- так БД может сразу прыгнуть по индексу
- по сути это "дай следующие 20 записей после этого timestamp", где timestamp используется как ключ
- время реально падает с секунд до примерно 100–200 мс

Что если timestamp не уникален, есть дубли:

Добавляем tie-breaker: (created_at, id) и в WHERE, и в ORDER BY:

WHERE (created_at, id) < ('2024-05-01 10:00:00', 98765)
ORDER BY created_at DESC, id DESC


Так пагинация остается быстрой и детерминированной, даже при одинаковых created_at.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Оптимизация SQL в бэкенде

Оптимизация SQL обеспечивает эффективную работу запросов в бэкенде, снижает задержки и повышает общую производительность системы.

Плохо оптимизированный SQL приводит к медленному отклику, высокой загрузке процессора и узким местам в приложениях с высокой нагрузкой.

✓ 1. Изучение планов выполнения запросов

Используйте команды EXPLAIN или EXPLAIN ANALYZE, чтобы понять, как база данных выполняет запрос.
→ Помогает выявить полное сканирование таблиц, неэффективные соединения, отсутствующие индексы или ненужную сортировку.

✓ 2. Индексирование для ускорения поиска

Создавайте индексы для столбцов, которые часто используются в запросах (например, поля поиска, внешние ключи).
Используйте составные индексы при фильтрации по нескольким столбцам.
Избегайте избыточного индексирования: каждый индекс замедляет операции вставки, обновления и удаления.

✓ 3. Избегайте использования SELECT *

Выбирайте только необходимые столбцы с помощью конструкции SELECT столбец1, столбец2.
→ Это сокращает объём передаваемых данных и повышает скорость выполнения запроса.

✓ 4. Оптимизация соединений (JOIN)

Используйте подходящие типы соединений (INNER, LEFT, RIGHT) в зависимости от задачи.

Убедитесь, что столбцы, используемые в соединениях, проиндексированы.

Избегайте объединения слишком многих таблиц в одном запросе — при необходимости разбивайте сложную логику.

✓ 5. Эффективное использование условий WHERE

Применяйте фильтрацию как можно раньше, используя избирательные условия.

По возможности используйте индексированные столбцы в фильтрах WHERE.

Избегайте использования функций в WHERE (например, LOWER(name)), так как они препятствуют использованию индексов.

✓ 6. Ограничение количества возвращаемых строк

Используйте LIMIT или OFFSET для пагинации вместо возврата огромных наборов данных.
→ Это повышает производительность фронтенда, которому не требуется вся информация сразу.

✓ 7. Избегание проблемы N+1 запросов

Возникает при получении связанных данных в циклах.

Вместо этого используйте соединения (JOIN) или эффективные пакетные запросы.

✓ 8. Использование кэширования

Кэшируйте часто выполняемые запросы на чтение с помощью Redis или Memcached.
→ Это снижает нагрузку на базу данных и значительно повышает скорость работы.

✓ 9. Нормализация там, где нужно, денормализация — когда это оправдано

Нормализация уменьшает избыточность и повышает согласованность данных.
→ Денормализация ускоряет операции чтения при высокой нагрузке, если производительность — приоритет.

✓ 10. Оптимизация операций вставки и обновления

Используйте пакетные вставки вместо поочерёдной вставки строк.

Избегайте ненужных обновлений: проверяйте, изменились ли значения, прежде чем выполнять обновление.

✓ 11. Разделение больших таблиц

Разделяйте большие таблицы по дате или региону для ускорения запросов.
→ Полезно для логов, аналитики или данных временных рядов.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Я предпочитаю формат [error, data], а не { error, data } для результатов асинхронных операций. Почему? Потому что кортеж гарантирует порядок. Ошибку ставим первой, чтобы потребитель не забывал о ней. У объекта порядок ключей не важен, и легко пропустить проверку поля error.

Такие мелкие решения в итоге делают API действительно удобным. Если хочешь поощрять обработку ошибок, ставь их вперед. Дай понять потребителю, что они существуют. Сделай так, чтобы проигнорировать ошибку было сложно. 🍦

И именно так и был разработан until-async: https://github.com/kettanaito/until-async

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Терминальный клиент для HTTP / GraphQL / gRPC с поддержкой SSH-туннелей, WebSocket, SSE, workflows, профилирования, OpenAPI и диффов ответов.

https://github.com/unkn0wn-root/resterm

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Сегодня решаю классическую задачу из распределенных систем:

как надежно стримить логи с нескольких реплик в хронологическом порядке?


Неожиданно, но ни один популярный инструмент контейнеризации это нормально не делает.

docker service logs, kubectl logs, stern, kubetail, k9s — все они просто перемешивают стримы в порядке получения. Стандартный костыль — пропустить вывод через | sort 🙃

Чтобы сделать это правильно, просто печатать логи по мере поступления нельзя, потому что более медленный стрим может прислать запись с более ранней меткой времени. Нужно понимать момент, когда запись можно выводить безопасно.

Вот как я решаю это в новой команде uc logs. Требуется две вещи:

1. Low watermark

Отслеживаем минимальный timestamp среди всех стримов и безопасно выводим буферизованные логи, у которых timestamp ниже этого watermark.

watermark = min(latest_timestamp for each stream)
sort and print all buffered logs where timestamp < watermark


2. Heartbeat timestamps

Что если контейнер просто замолчит? Тогда весь вывод зависнет, потому что watermark не будет сдвигаться.

Решение - периодически отправлять пустые heartbeat-записи с текущим timestamp на сервере. Это по сути обещание: "У меня нет логов, которые старше этого времени".

Это позволяет клиенту продвигать watermark без блокировки вывода. На практике интервал 500 мс – 1 сек работает нормально.

Что насчет несинхронизированных системных часов?

Тут особо ничего не сделаешь, не усложняя систему. Просто детектируем проблему, предупреждаем пользователя и живем дальше.

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

AWS открыл бесплатный доступ к SimuLearn до 6 января!

✓ Реальные симуляции, чтобы прокачать навыки по облакам
✓ Без кредитки и без риска внезапных списаний
✓ EC2, NoSQL, архитектура, траффик под нагрузкой и другое

Один из топовых ресурсов:

ссылка

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Пиковый опыт разработки на TypeScript в бэкенде.

Определяешь маршрут, возвращаешь данные, всё полностью типобезопасно.

Типобезопасность тянется до фронтенда через RPC-подобный коннектор.

Документация по API генерируется для всех ответов.

OpenTelemetry заводится меньше чем за 10 строк.

Живём в интересное время.

Код тоже очень хороший, чувак написал его примерно за час.

https://github.com/SaltyAom/elysia-prisma-better-auth-example

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Еще одна книжка на полку. Пятое издание. Подборка статей, собранных Стоунбрейкером, Питером Бейлисом и Джозефом Хеллерстейном. PDF доступен бесплатно.

redbook.io/pdf/redbook-5th-edition.pdf

👉 @BackendPortal

Читать полностью…

Backend Portal | Программирование

Удаляйте ChatGPT. Вы не умеете им пользоваться.

Большинство пользователей спамит в ИИ всякую чушь — просят рассказать анекдот, изливают душу и используют как Гугл.

Российский тимлид OpenAI Вадим Петрич рассказывает в «Доктор GPT» как извлекать из нейронок максимум пользы. Это очень интересно:

• ТОП №1 нейросеть, генерирующая видео без цензуры вообще
• Готовые промты на все случаи жизни
• Инсайды и разработки от китов индустрии

Подпишитесь, с Доктором GPT нейронки станут инструментом роста, а не безделушкой:
/channel/+K65EHRh_x_c2OTli

Читать полностью…

Backend Portal | Программирование

Почему JSON жрет твой CPU

Твой API тупит. Ты думаешь что база медленная, сеть лагает. Но реальная пробка может быть в том формате, на котором всё общается.

JSON это не формат данных. Это текст.

Каждый раз, когда ты отправляешь {"id": 12345}, сервер платит скрытый "налог на парсинг". Даже самые быстрые парсеры вроде simdjson упираются в аппаратные ограничения, которых у бинарных форматов просто нет.

Разложим по технике.

1. Цена на CPU (state-machine против арифметики)

JSON (текст):

Чтобы прочитать число 12345, CPU получает сырые байты. Даже оптимизированный парсер должен пройти через state machine:

- искать структурные символы (: , { }).
- проверять escape-последовательности.
- а потом конвертировать строку в число:
цикл: взять char, вычесть '0', умножить накопленное на 10, прибавить.

Это прыжки в ветках, пропуски кеша, ситуации, где CPU просто ждет.

Protobuf (бинарный):

Отправляет Varint (для маленьких чисел) или фиксированный формат.

fixed32 => просто memcpy. Никакого парсинга.

Varint => читаешь байт, смотришь флаг в старшем бите (MSB), решаешь, идет ли число дальше.

Результат: несколько битовых операций. На нагрузках с большим количеством чисел бинарный формат фундаментально быстрее.

2. Стоимость по сети (энтропия против повторов)

JSON:

[
{"status": "active"},
{"status": "active"}
]


Ты передаешь ключ "status" снова и снова.

Контраргумент:

gzip всё решит!


Ответ:

gzip решает сеть, но ест CPU.


Тебе нужно:

Serialize JSON → Compress → Send
и у получателя наоборот: Receive → Decompress → Parse JSON.

Ты сжимаешь текст, который вообще не должен повторяться.

Protobuf:

Схема отдельно, данные отдельно. На проводе вместо "status" просто ID поля. [Tag: 1][Value: "active"]. Сжатие уже почти ненужно —> полезной нагрузки меньше.

3. Цена надежности (Schema-on-Read)

JSON это "схема при чтении". Ты получаешь кусок текста и надеешься, что id правда число. В итоге:

if (typeof id !== 'number') ...
или тащишь валидатор вроде Zod/Pydantic, что снова жрет CPU.

Protobuf — "схема при записи".

Контракт жесткий = типы известны заранее, и на границе сериализации ты получаешь гарантии. Валидация есть, но намного дешевле.

JSON удобен для публичных API, потому что читаемый и дружелюбный.

Но в высоконагруженных микросервисах JSON это налог. Ты тратишь железо, чтобы каждый раз разбирать текст.

gRPC/Protobuf это не сверхчудо. Ты просто переносишь сложность с рантайма (парсинг текста) в билд-стадию (генерация кода).

И CPU говорит спасибо. 🥰

👉 @BackendPortal

Читать полностью…
Subscribe to a channel