Мастерская IT-решений
149 subscribers
45 photos
2 videos
30 links
О проектировании систем и их взаимодействии. Теория и практические кейсы
Download Telegram
А вот и новости №3 и №4. Банк опередил и анонсировал даже раньше меня.

Осенний сезон ожидается насыщенным и иногда даже горячим.
У кого какие конференции запланированы на осень?
Forwarded from ИТ ПСБ
💎 Наша коллега Дарья Борисова представит ПСБ сразу на двух ИТ-конференциях в Санкт-Петербурге.

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

Приходите поддержать коллегу в Петербурге или онлайн:

🟣на крупнейшей региональной ИТ-конференции России «Стачка» — 2 октября;

🟣на конференции по системному и бизнес-анализу Flow 2025 Autumn — 3 октября.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1😍1
♻️ 3. Безопасность ♻️

📜 Требования
✏️ Конфиденциальность: Данные читателей (персональные данные, история чтения) должны быть защищены от несанкционированного доступа.
✏️ Аутентификация и Авторизация: Строгое разграничение прав между библиотекарями (могут выдавать книги) и администраторами (могут управлять пользователями, настраивать систему).
✏️ Аудит: Вести лог всех действий, особенно связанных с изменением данных (изменение размера штрафа, удаление записи о книге, сброс пароля).

📉 Способы исполнения

📓 Паттерны:
RBAC (Role-Based Access Control): Система прав доступа, основанная на ролях. Создаются роли Librarian и Admin, каждой роли назначаются разрешения на конкретные endpoints API или экраны UI.

📓 Инструменты и практики:
〰️ HTTPS: Обязательное использование шифрованного соединения для всего трафика.
〰️ Хэширование паролей: Пароли пользователей (библиотекарей и админов) должны храниться в базе данных только в виде хэшей.
〰️ Валидация входных данных: Защита от SQL-инъекций и XSS-атак путем использования ORM или подготовленных выражений
〰️ JWT (JSON Web Tokens) или OAuth 2.0: Для управления сессиями пользователей после входа в систему.
1
♻️ 4. Масштабируемость ♻️

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

📗Способы исполнения
📐 Вертикальное масштабирование: Увеличение ресурсов существующего сервера (более мощный CPU, больше RAM). Минусы: имеет физический предел.
📐 Горизонтальное масштабирование: Добавление новых серверов-клонов с приложением за балансировщиком нагрузки. Более современный и гибкий подход. Для этого приложение должно быть stateless (не хранить состояние сессии на сервере, а использовать, например, JWT или хранилище сессий в Redis).


📗 Архитектура
Выбор микросервисной архитектуры (разделение на сервис каталога, сервис выдачи, сервис отчетности) упростит независимое масштабирование отдельных частей системы в будущем. Приведу небольшой спойлер, который мы будем разбирать подробнее в секции архитектуры: для старта работы библиотечной системы монолитная архитектура является более оправданной. А почему - обсудим :)
♻️ 5. Удобство использования и Совместимость ♻️

📜 Требования
✏️ UI/UX: Интерфейс должен быть интуитивно понятным для библиотекарей с минимальным обучением. Критичные операции (сканирование штрих-кода книги и читательского билета) должны выполняться с минимальным количеством кликов.
✏️ Кросс-браузерность: Веб-интерфейс должен корректно работать в современных браузерах (Chrome, Firefox, Safari, Edge).
✏️ Мобильность: Адаптивный интерфейс или отдельное мобильное приложение для работы с портативными сканерами штрих-кодов.

📕 Способы исполнения

🗝 Фреймворки: Использование современных frontend-фреймворков (React, Vue.js, Angular)
🗝 User Testing: Проведение тестирования с реальными библиотекарями на ранних этапах на базе прототипов в Figma).



♻️ 6. Тестируемость и Поддерживаемость ♻️

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

📒 Способы исполнения

📁 Паттерны:
🗳 Модульная архитектура: Следование принципам SOLID и использование Dependency Injection для создания слабосвязанного кода, который легко тестировать.

📁 Инструменты и практики:
🗳 Покрытие кода тестами: Написание модульных (Unit), интеграционных (Integration) и end-to-end (E2E) тестов.
🗳 CI/CD: Настройка автоматизированных пайплайнов (например, в GitLab CI/CD, GitHub Actions) для запуска тестов и развертывания на тестовые/продуктивные среды.
1
Новость №5.

В сентябре вышла моя первая статья на Хабре в блоге ПСБ. Охватить хотелось как можно больше, поэтому она получилась лонг-ридом.

Описала, кажется, все подводные камни, с которыми сталкивалась при проектировании API. Может, найдете что-то для себя!

За 2 недели более 5 тыс прочтений. Для меня это знак, что я создаю актуальные материалы. Пошла работать дальше.

Хотите посмеяться? когда вышла эта статья, по стечению обстоятельств, мое имя появлялось в новостной ленте банка 4 раза по разным поводам, поэтому неделю 22-26 сентября медийка Банка назвали в мою честь (в шутку)

https://habr.com/ru/companies/psb/articles/949246/
🔥2
Что делать с системой при разных значениях RPS?

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


Значение RPS (Requests per second) определяет количество запросов, обрабатываемых системой каждую секунду. Выбор конкретных мер и сложность архитектуры зависят от множества факторов, включая не только само значение RPS, но и типы запросов, частоту всплесков нагрузки, необходимость поддержания высокой доступности и устойчивости системы.

🌀 Основные уровни значений RPS и рекомендуемые меры

🟢 Низкая нагрузка (< 10 RPS)

Примеры ситуаций: небольшие внутренние сервисы, прототипы, проекты начального этапа разработки.

Подходящие решения:

- Монолитная архитектура
- Локальная база данных
- Минимальные средства мониторинга
- Отказ от кеширования или использование простого кеша (Redis для хранения сессий).

🟠 Средняя нагрузка (~10–100 RPS)

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

⚙️ Рекомендуемые шаги:

- Разделение на отдельные модули (Service-Oriented Architecture, SOA);
- Кеширование на уровне сервера приложений (Varnish, Redis, Memcached);
- Оптимизация баз данных (индексация, репликация master-slave);
- Автоматическое масштабирование хостинга (AWS Auto Scaling, Kubernetes HPA).

🔴 Высокая нагрузка (~100–1000 RPS)

Примеры ситуаций: крупные веб-сервисы, корпоративные CRM, большие e-commerce площадки.

🚀 Необходимые меры:

- Микросервисная архитектура (каждый сервис отвечает за свою область);
- Балансировка нагрузки (Nginx, HAProxy, AWS ELB / ALB);
- Горизонтальное масштабирование (масштабирование вычислительных ресурсов в облаке);
- Использование шардирования (разбиение базы данных на части);
- Интеграция CDN (Content Delivery Network) для ускорения доставки статического контента.

🔵 Очень высокая нагрузка (> 1000 RPS)

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

🪄 Какие технологии применять:

- Полностью асинхронная обработка запросов (event-driven architecture, очереди сообщений Kafka, RabbitMQ);
- Распределённые хранилища данных (Cassandra, MongoDB);
- Географически распределённая инфраструктура (multi-datacenter deployment);
- Расширенное кэширование (использование многоуровневых прокси-кешей, Redis Cluster);
- Высокая степень автоматизации деплоев и мониторинг (Kubernetes, Docker Swarm, CI/CD pipeline).


🔝 Общие принципы выбора подхода

- Простота против сложности: Чем ниже RPS, тем проще должно быть решение. Это очевидно, но сказать стоит: избегайте избыточной сложности там, где она не нужна.
- Масштабируемость: Подбирайте инфраструктуру, способную выдержать пиковые нагрузки (особенно сезонные всплески активности пользователей).
- Надёжность: Важнее всего гарантировать доступность сервиса при любом количестве запросов (это не всегда важнее всего. На своих докладах осеннего сезона я подробно разбираю этот аспект).
- Стоимость поддержки: Усложнение инфраструктуры повышает стоимость обслуживания и внедрения новых функций.

📍📍 Итоговая рекомендация

При достижении порога в ~100 RPS целесообразно задуматься о переходе к более сложной инфраструктуре и подготовке среды к росту нагрузки. Однако решающее значение имеет также качество самих запросов: если запросы сложные (например, требуют больших вычислений или объёмных выборок из базы данных), начать подготовку стоит заранее, ещё при меньших значениях RPS.
1
Как использовать кеширование эффективно

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

🧲 Что лучше кешировать
– Часто читаемые, редко меняющиеся данные (Каталог товаров, справочники, контент страниц, настройки)
Результаты тяжелых вычислений (Агрегированная статистика, отчеты, рекомендательные выборки)
– Сессии пользователей

♨️ Что НЕ надо кешировать
– Часто меняющиеся данные (Текущий баланс счета, место водителя такси на карте)
– Чувствительные/персональные данные (если только кеш не надежно зашифрован).
– Уникальные данные, которые вряд ли будут запрошены повторно.

🔑 Стратегия инвалидации
Инвалидация - это обновление кеша. Политика ее выбора - самая сложная часть.
Time-To-Live (TTL)
Самый простой способ. Устанавливаем время жизни записи в кеше. Подходит для данных, где не будет слишком критично, если данные ненадолго"протухнут" (например, список новостей).
Инвалидация по событию
или "Write-Through/Write-Behind". При любом изменении данных в источнике нужно обновлять или удалять соответствующие данные в кеше. Этот подход позволяет оставлять данными в наиболее свежем состоянии, но требует сложной логики.
Отложенная запись
или "Write-Behind". Запись данных сначала происходит в кеш, а затем асинхронно "сбрасывается" в основное хранилище. Повышает производительность записи, но есть риск потери данных при сбое.

📇 Выбор размера кеша и политики вытеснения


Что делать, когда кеш заполнен? Нужно почистить его от лишних данных. Как определить, какие данные являются лишними? Есть специальные политики
- LRU (Least Recently Used) — вытесняются давно неиспользуемые данные (фильтр по дате)
- LFU (Least Frequently Used) — вытесняются реже всего используемые данные (фильтр по частоте обращения)

🟰 Многоуровневое кеширование

Уровень 1 (L1): Внутрипроцессный кеш (в памяти приложения). Очень быстрый, но не разделяемый между экземплярами приложения.
Уровень 2 (L2): Внешний кеш (Redis, Memcached). Чуть медленнее из-за сетевого взаимодействия, но разделяемый между всеми экземплярами приложения.

Дальше разберем виды кеширования
А вот и новость №6
Сегодня вылетаю на Merge Baltic!
Есть здесь те, кто тоже туда едет?
Forwarded from ИТ ПСБ
🐈 Наши коллеги едут в Светлогорск — чтобы представить ПСБ на Merge Baltic 2025.

➡️Роман Миловидов и Данила Шалыгин поделятся опытом выстраивания процесса управления потоком продуктовых задач в соответствии с целями бизнес-направления. Ответят на вопросы, как понять предназначение отдела, как использовать рефлексию в системах discovery и delivery, как визуализировать end2end процесс для управления потоком задач.

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

Merge — крупнейшая профессиональная конференция, где встречаются эксперты из самых разных сфер ИТ: от разработки до маркетинга.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🤩2👍1
Это ли не прекрасно...?
Виды кеширования и когда их выбирать

По расположению (архитектурный уровень)

🔹 Клиентское кеширование
Как работает: Браузер или мобильное приложение хранит статику (CSS, JS, картинки) и даже данные (via LocalStorage).
Когда использовать: Для снижения нагрузки на сервер и ускорения отклика для конечного пользователя. Рекомендуется использовать HTTP-заголовки Cache-Control, ETag.

🔹 Кеширование на прокси (CDN)
Как работает: Сеть доставки контента (Cloudflare, AWS CloudFront) кеширует статический и даже динамический контент на своих edge-серверах по всему миру.
Когда использовать: Для раздачи статики (изображения, видео) и динамического контента глобальной аудитории. Снижает задержку.

🔹 Веб-сервер / Кеш обратного прокси
Как работает: Nginx, Varnish кешируют целые HTML-страницы или API-ответы перед приложением.
Когда использовать: Для разгрузки backend-серверов. Идеально для страниц, которые одинаковы для многих пользователей (блог, новостная лента).

🔹 Кеширование приложения (In-Memory)
Как работает: Приложение хранит данные в своей оперативной памяти (например, HashMap в Java, dict в Python) или использует распределенный кеш (Redis, Memcached).
Когда использовать: Для кеширования результатов запросов к БД, тяжелых вычислений, сессий пользователей. Самый гибкий вид.

🔹 Кеширование базы данных
Как работает: Сама СУБД имеет внутренний кеш для результатов запросов и индексов.
Когда использовать: Работает "из коробки", но настраивается под конкретную СУБД. На него можно влиять, но основное управление — у базы данных.


По стратегии доступа

🔺Cache-Aside (Lazy Loading)
Как работает
1. Приложение ищет данные в кеше.
2. Если данные в кеше не найдены, берет из БД.
3. Приложение кладет данные в кеш

Простота, отказоустойчивость (при падении кеша система работает напрямую с БД).
Возможность пропуска кеша на каждый запрос, риск "стартового шторма" (т.е. когда за каждым запросом обращаемся в базу) после сброса кеша.

Когда использовать
Наиболее распространенный подход. Идеален для читаемой нагрузки с предсказуемыми данными для кеширования.

🔺 Read-Through
Как работает
Приложение всегда читает из кеша. Если данных нет, кеш сам загружает их из БД и возвращает приложению.

Чище архитектура приложения.
Требует от кеша возможности загружать данные (например, Redis Modules).

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

🔺 Write-Through

Как работает
Приложение записывает данные в кеш, а кеш синхронно записывает их в БД.

Гарантирует консистентность между кешем и БД.
Высокая задержка записи.

Когда использовать
Когда консистентность критически важна, а производительность записи — нет.


🔺 Write-Behind (Write-Back)
Как работает
Приложение записывает данные в кеш, который асинхронно (с задержкой) обновляет БД.

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

Когда использовать
Для данных, которые можно временно потерять или где запись очень частая (например, счетчики просмотров, лайки).
На что обратить внимание при внедрении кеша

🔛 Несогласованность данных
Самая частая проблема. Вы кешируете данные, они меняются в источнике, а в кеше остаются старые.
Решение: Грамотная стратегия инвалидации (TTL или по событию).

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

🔛 Несанкционированное прокникновение
Запросы по несуществующим ключам (например, user_id=-1) постоянно пролетают мимо кеша и бьют по БД. Решение: Кешировать сам факт отсутствия данных (например, положить null с коротким TTL).

🔛 Разрушение кеша
Одновременная инвалидация очень популярного ключа (например, по истечению TTL), что приводит к лавине запросов в БД для его пересчета.
Решение: Использование механизма "блокировки" (mutex), чтобы только один поток пересчитывал значение, а остальные ждали.

🔛 Проблема "горячего" ключа
Один ключ (например, данные супер-популярного товара) получает огромное количество запросов, создавая нагрузку на один узел распределенного кеша.
Решение: Репликация "горячего" ключа на несколько узлов или его дублирование в локальном L1-кеше приложения.


С чего начать при внедрении кеша?
Небольшой план действий для начинающего кошатника 🐱 КЕШатника:
1. Измерьте и найдите самое медленное место.
2. Выберите тип кеша, который поможет в решении этой проблемы.
3. Внедрите простую стратегию (например, Cache-Aside с TTL).
4. Продумайте инвалидацию.
5. Мониторьте эффективность (количество попаданий и промахов кеша) и будьте готовы к подводным камням.

Часто самый большой выигрыш дает кеширование на уровне веб-сервера (Nginx) для статики и HTML и использование Cache-Aside паттерна с Redis/Memcached для данных приложения.
1👏1
Хотите несколько практических задач?
Такой опрос я проводила на одном из докладов, попробуем в онлайне такое провести. Здесь и задачи усложнились, и времени на подумать будет больше.

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

Варианты ответов

1️⃣ Кеш на уровне БД: Использовать встроенный кеш запросов базы данных. Время жизни — 10 минут.

2️⃣ Кеш на уровне приложения: Разместить в памяти приложения (например, с помощью Redis) объект "Профиль пользователя". Использовать стратегию LRU (Least Recently Used) и время жизни (TTL) 5 минут.

3️⃣ Кеш на уровне клиента: Отправлять заголовки HTTP-кеширования браузеру пользователя со временем жизни 1 час.

Пишите в комментарии свой вариант.
Ответ будем разбирать вечером.
🔥3
Правильный вариант:
2️⃣
(Кеш на уровне приложения).

Разбираем почему так.

• Почему НЕ вариант 1 (БД)
Кеш на уровне БД снимет нагрузку с движка базы, но не уменьшит количество самих запросов к ней. Он также негибкий — при изменении одного профиля инвалидировать кеш сложно.

• Почему НЕ вариант 3 (Клиент)
Данные профиля персональны и могут меняться. Если закешировать их в браузере на час, пользователь может не сразу увидеть свои обновления или изменения на странице друга. Кроме того, этот кеш не снимет нагрузку с серверной части.

• Почему вариант 2 (Приложение)
Это идеальный компромисс.
Расположение: Кеш в Redis расположен близко к приложению, снимает нагрузку с базы данных и drastically уменьшает количество запросов к ней.
Стратегия вытеснения: LRU отлично подходит для соцсети, так как вытесняет профили наименее активных пользователей, оставляя в кеше "горячие" данные.
Время жизни (TTL): 5 минут — разумный баланс между актуальностью данных (изменения станут видны в течение 5 минут) и эффективностью кеша.

Совпало?
будем делать еще задачку?
❗️Новая задачка! Потренируемся?

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

Варианты решения:

1️⃣ Кеш на уровне приложения: Кешировать баланс пользователя в Redis на 30 секунд для снижения пиковой нагрузки на систему.

2️⃣ Кеш на уровне БД: Настроить репликацию базы данных и читать историю операций с реплики, которая может отставать на несколько секунд.

3️⃣ Без кеширования: Не использовать кеш для этих данных вообще. Все запросы отправлять непосредственно в основную базу данных.

Кидайте свои варианты в комментарии. Разбирать будем вечером
Правильный вариант:
3️⃣ (Без кеширования), с оговоркой на вариант 2️⃣ для некоторых данных.

Объяснение
🟩 Почему вариант 3️⃣ — основной: Для строго консистентных данных, где критична абсолютная актуальность (например, текущий баланс), кеширование опасно. Пользователь может увидеть устаревшие данные и, например, совершить платеж, думая, что у него есть деньги. Любой TTL > 0 создает риск расхождения.

🟥 Почему не вариант 1️⃣ (Приложение): 30 секунд — это огромное окно неконсистентности для финансовых данных. Стратегия абсолютно неприемлема в контексте финансов.

🟧 Оговорка про вариант 2️⃣ (БД): Для истории операций, которая только добавляется, но не удаляется, можно использовать чтение с реплик (это форма кеширования). Пользователь может не заметить отставание в пару секунд, а нагрузка на основную базу снизится. Но для баланса это недопустимо.

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

Что с ИТ-рынком?
Дефицит кадров? Перенасыщение? Что делать и куда бежать?
https://habr.com/ru/companies/ddosguard/articles/960606/

Статья холиварная (особенно в комментах).

От себя добавлю: в целом согласна с мнением редакции, но есть пара пунктов....

Работа для айтишника не может закончиться
Может. Для тех кто работает на создание ПО. Кто на поддержке, у того ситуация стабильнее.

В январе 2025 «Бизнес FM» стращал массовыми сокращениями в IT-отрасли (в реальности, если судить по приведенной Минцифры статистике, произошло прямо противоположное)
Противоположное? Серьёзно? На конференциях осеннего сезона я активно собираю статистику этого аспекта. И ещё никто не сказал мне "сокращения в моей компании? Не, не слышал..."

Мне интересно, что вы скажете. Что думаете о рынке? Что задело в статье? Что планируете делать дальше?
Делитесь!))
Ну очень приглянулось 😅
Весёлых вам праздников!
3