Мастерская IT-решений
149 subscribers
45 photos
2 videos
30 links
О проектировании систем и их взаимодействии. Теория и практические кейсы
Download Telegram
Котики!
Не теряемся! Я пока под завалами своих проектов, и нет времени писать в канал. Скоро всё раскидаю и вернусь.
Коротко о том, что хотят мои заказчики, показала на картинке 😆
причем так происходит везде.
😁1
Ура! Я вернулась!
И конечно,  такое длительное затишье я могу оправдать только большим количеством приятных новостей и постов. Да будет так!
Но делиться буду постепенно. ☺️


Новость N1
Вы классные! Просто так. Ну и потому что дождались меня и не разбежались!

Новость N2
Давно хотела поделиться, да всё некогда было. Летом я стала амбассадором Банка ПСБ, где работаю и наслаждаюсь каждым днём своей профессиональной деятельностью. 🌟

Сразу скажу: рекомендую только то, что действительно люблю сама.

Зачем вообще рассказываю?

Хочется продемонстрировать, как здорово и вдохновенно можно провести своё рабочее время, получать ценные знания и развивать профессиональные навыки именно здесь. Ведь выяснилось, что Банк незаслуженно недооценён среди IT-сообщества, хотя, на мой взгляд, заслуживает большего внимания. Поэтому я хочу изменить ситуацию.

За прошедший год Банк стал важной частью моей жизни — и это совсем не критика, а искренняя похвала. Благодаря Банку я начала танцевать, заниматься йогой, посещать каток, ходить на местные мероприятия вроде TED-talks, готовиться к выступлениям на внутренних и внешних мероприятиях, учиться ведению переговоров и публичным выступлениям. То есть всему тому, до чего раньше никак не доходили руки, теперь можно заняться вместе с коллегами!

Хотите читать истории о жизни внутри банка? Если да, то буду иногда делиться закулисьем моей работы.

Всегда открыта вашим отзывам и мнениям. Честный диалог помогает двигаться вперёд всем вместе.
2
Нефункциональные требования
Мы рассмотрели, как проектировать Базу, а теперь пора уделить время нефункциональным требованиям нашей библиотечной системы. Подумаем, что учесть и как обечпечить те характеристики, которые описываются в нефункциональных требованиях.
Рассмотрим следующие характеристики:
1. Производительность
2. Надежность и Доступность
3. Безопасность
4. Масштабируемость
5. Удобство использования и Совместимость
6. Тестируемость и Поддерживаемость

♻️ 1. Производительность ♻️

Требования
• Время отклика:
– Большинство операций (поиск книги, оформление выдачи, возврат) должны выполняться менее чем за 2 секунды.
– Операции формирования сложных отчетов (например, за год) могут занимать до 30 секунд.
• Пропускная способность:
– Система должна выдерживать пиковую нагрузку до 50 одновременных операций (например, в часы "наплыва" читателей перед закрытием или в выходной день).
• Масштабируемость:
– Система должна иметь возможность масштабирования для обслуживания большего количества филиалов или пользователей без полной переработки архитектуры.

Способы исполнения
• Паттерны:
– Кэширование (Caching): Использование кэша (например, Redis или Memcached) для часто запрашиваемых и редко изменяемых данных: список популярных книг, информация о читателях (при частом обращении), справочники (жанры, авторы).
– Пагинация (Pagination): Все списки (результаты поиска, история выдач) должны возвращаться частями (по 20-50 записей), а не целиком.
– Асинхронная обработка (Async Processing): Для длительных операций (формирование объемных отчетов, рассылка уведомлений о задолженностях) использовать асинхронные задачи (через RabbitMQ, Kafka или Celery). Пользователь получает уведомление о готовности отчета, а не ждет его генерации в основном потоке.
• Инструменты:
– База данных: Выбор производительной СУБД (PostgreSQL или MySQL), создание индексов, о которых говорили ранее.

🎲 Расчеты
– Оценка нагрузки: Предположим, в библиотеке 10 активных библиотекарей. Каждый совершает 1 операцию в минуту в спокойном режиме и до 5 операций в минуту в пиковом. Итого: 10 * 5 = 50 операций/мин (≈ 0.83 ops/sec). Это скромная нагрузка, поэтому внимание можно уделить простоте реализации и поддерживаемости системы.
Никаких особенных подходов не требуется для обеспечения такой нагрузки, но можно добавить:
- Нужно оптимизация SQL-запросов
- Рекомендуется использовать простую архитектуру
- Полезно иметь систему мониторинга основных метрик (CPU, память, запросы к базе данных). Это позволит оперативно реагировать на изменения нагрузки или появление узких мест.
Подробнее о RPS поговорим позже.
1
Продолжаем разбирать нефункциональные требования.

♻️ 2. Надежность и Доступность
♻️

📜Требования
✏️ Доступность: Система должна быть доступна 99.9% времени в рабочие часы библиотеки (это чуть более 8 часов простоя в год). Критично, чтобы система не "падала" в часы пиковой нагрузки.
✏️ Целостность данных: Не допускается потеря данных о выдачах, читателях или книгах. Все финансовые операции (начисление/списание штрафов) должны быть транзакционными.
✏️ Восстановление после сбоев: В случае сбоя система должна восстанавливаться из последней резервной копии с минимальной потерей данных (целевой показатель восстановления - RTO < 1 часа, целевой показатель точки восстановления - RPO < 15 минут).

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

📘 Паттерны:
🔸 Репликация базы данных: Настройка Master-Slave репликации. Slave-реплика может использоваться для чтения (например, для отчетов), а также служить "горячим" резервом на случай падения Master.
🔸 Резервное копирование (бекапы): Регулярное (ежедневное) автоматическое резервное копирование базы данных и файловых Assets (например, сканы документов читателей). Хранение бэкапов не только на основном сервере, но и в удаленном хранилище (например, в облаке Яндекса).


📘 Инструменты:
🔹 Мониторинг: Использование систем мониторинга (Prometheus + Grafana, Zabbix) для отслеживания доступности, нагрузки и потребления ресурсов.
🔹 Балансировщик нагрузки: Например, nginx для распределения запросов между несколькими экземплярами приложения.


📘 Архитектура:
Для обеспечения 99.9% доступности достаточно одной ноды (сервера) приложения и одной ноды базы данных с правильно настроенной репликацией и мониторингом. Переход на отказоустойчивый кластер (например, с несколькими нодами приложения за балансировщиком) потребуется при более строгих требованиях (99.99%).
А про виды девяток и их влияние поговорим немного позже
2
А вот и новости №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