← Все темы

System Design

Вопросов: 36

System Design — это процесс проектирования архитектуры сложных программных систем.
Зачем нужен System Design:
- Обеспечение масштабируемости: чтобы система могла эффективно работать при росте нагрузки.
- Улучшение надёжности: минимизация сбоев и обеспечение устойчивости.
- Оптимизация производительности: быстрое и эффективное выполнение задач.
- Облегчение поддержки и расширения: понятная структура для будущих изменений.
- Координация командной работы: единое понимание архитектуры для разработчиков, тестировщиков и других специалистов.

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

Нефункциональные требования определяют, как система должна работать: её характеристики и ограничения.
- Пример: время отклика приложения не должно превышать 2 секунд.
- Пример: система должна обеспечивать безопасность и защиту данных.

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

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

Преимущества микросервисной архитектуры:
- Гибкое масштабирование — масштабируются только необходимые сервисы.
- Повышенная отказоустойчивость — сбой одного сервиса не блокирует всё приложение.
- Возможность использовать разные технологии для каждого микросервиса.

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

CAP-теорема — это фундаментальное утверждение в распределённых системах, гласящее, что система не может одновременно обеспечить более чем два из трёх свойств:
- Consistency (Согласованность): все узлы видят одинаковые данные в одно и то же время
- Availability (Доступность): каждый запрос получает ответ, без гарантии актуальности данных
- Partition tolerance (Устойчивость к разделению сети): система продолжает работать при потере связи между узлами

Дополнения к CAP-теореме:
- При сетевых разделениях (Partition) необходимо выбирать между Согласованностью и Доступностью.
- В реальности разделения сети случаются часто, поэтому современные системы проектируют компромиссы между CAP-свойствами.
- PACELC-теорема расширяет CAP, учитывая компромиссы и при отсутствии разделения сети (Partition):
- Если имеется разделение (Partition), выбор между Availability и Consistency
- Иначе выбор между задержкой (Latency) и согласованностью (Consistency)

Практическое применение:
- Системы, где важна целостность данных (например, банковские сервисы), предпочитают Consistency и Partition tolerance (CP).
- В системах с высокой нагрузкой и требованиями к отказоустойчивости (например, социальные сети) выбирают Availability и Partition tolerance (AP).
- Разработчики проектируют архитектуру, основываясь на требованиях к бизнес-логике и техническим ограничениям, балансируя свойства CAP.

Горизонтальное масштабирование — это добавление новых серверов или узлов в систему для распределения нагрузки.
- Позволяет обрабатывать больше запросов параллельно.
- Часто используется в распределённых системах и облачных сервисах.
- Пример: добавление новых серверов в кластер баз данных или веб-серверов.

Вертикальное масштабирование — это увеличение ресурсов существующего сервера (CPU, RAM, диск).
- Улучшает производительность одного узла.
- Применяется, когда масштабировать количество серверов сложно или дорого.
- Пример: апгрейд железа сервера базы данных.

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

Read/Write split – разделение запросов на чтение и запись между разными серверами. Решает проблему нагрузки на базу данных, повышает производительность и масштабируемость.
- Записи идут на мастер-сервер, чтения обслуживаются с реплик.
- Уменьшает блокировки и задержки при одновременной работе.

Кеширование – хранение часто запрашиваемых данных в быстром доступе (память, распределённый кеш). Решает проблему латентности запросов и нагрузки на базу или сервисы.
- Ускоряет доступ к данным, снижает затрату ресурсов.
- Может использоваться на разных уровнях: клиент, сервер, база данных.

Партиционирование – разделение больших таблиц или данных на части по ключу или диапазону. Решает проблему производительности запросов, управления большими объёмами данных.
- Улучшает эффективность поиска и обслуживания данных.
- Позволяет масштабировать данные горизонтально.

Load Balancer — это устройство или программный компонент, который распределяет входящий сетевой трафик между несколькими серверами для оптимизации нагрузки, повышения производительности и отказоустойчивости.
Роль в системе:
- Повышение доступности (если один сервер падает, трафик перенаправляется на другие)
- Балансировка нагрузки для избежания перегрузки отдельных серверов
- Улучшение масштабируемости путем добавления новых серверов

Reverse Proxy — это сервер, который принимает запросы от клиентов и пересылает их одному или нескольким backend-серверам, скрывая их внутреннюю структуру от клиентов.
Роль в системе:
- Абстрагирование backend-серверов и их IP-адресов
- Кэширование для ускорения обработки запросов
- Обеспечение безопасности через фильтрацию и ограничение доступа
- SSL-терминация, разгрузка шифрования
- Балансировка нагрузки в некоторых случаях (иногда Reverse Proxy и Load Balancer могут совмещаться)

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

Влияние выбора на архитектуру системы:
- SQL подходит для сложных транзакций, строгой целостности данных и сложных запросов, требует централизованного управления.
- NoSQL лучше для распределённых систем с большими объёмами данных, высокой нагрузкой и горизонтальным масштабированием.
- Выбор определяет структуру данных, схемотехнику, способ масштабирования и требования к согласованности, влияя на дизайн приложения и инфраструктуры.

Выбор СУБД для проекта зависит от требований к данным и нагрузке:
- PostgreSQL — реляционная СУБД с поддержкой сложных запросов и транзакций. Хорошо подходит для систем с требованием к целостности данных, аналитике, сложным связям.
- MongoDB — документоориентированная база данных, гибкая в структуре данных, удобна для динамических схем, быстрого прототипирования, проектов с нефиксированной структурой.
- Cassandra — распределённая колоночная СУБД, ориентирована на масштабируемость и высокую доступность, подходит для обработки больших объёмов данных, отказоустойчивых приложений с высокими нагрузками.
Итог: если важна строгая структура и транзакции — PostgreSQL; если гибкость схемы и быстрая разработка — MongoDB; если масштабируемость и отказоустойчивость — Cassandra.

Шардирование (sharding) — это метод горизонтального разделения базы данных на части, называемые шардами, каждая из которых хранит часть данных.
Как помогает масштабировать базы данных:
- Уменьшение нагрузки на отдельные серверы за счёт распределения данных.
- Повышение производительности обработки запросов, так как запросы обрабатываются параллельно на разных шардах.
- Горизонтальное масштабирование, позволяющее добавлять новые шарды по мере роста объёма данных.
- Улучшение отказоустойчивости за счёт изоляции данных в разных шардах.
Таким образом, шардирование позволяет эффективно управлять большими объёмами данных, улучшая скорость и надёжность работы базы.

Репликация данных — это процесс копирования и синхронизации данных между несколькими серверными узлами или базами данных для обеспечения отказоустойчивости, доступности и распределённости информации.
Виды репликации:
- Мастер-слейв (Master-Slave): данные записываются на главный сервер (мастер), копируются на подчинённые (слейвы). Слёвы обычно только для чтения.
- Мастер-мастер (Master-Master): несколько серверов могут принимать и записывать данные, обеспечивается синхронизация между ними.
- Асинхронная репликация: данные копируются с задержкой, возможна временная рассогласованность.
- Синхронная репликация: запись считается успешной только после успешной записи на все реплики, обеспечивает консистентность.
- Мульти-мастер (Multi-Master): расширенная версия мастер-мастер, с более сложным решением конфликтов.
Основные цели репликации:
- Повышение доступности и масштабируемости данных.
- Обеспечение резервного копирования и защиты от сбоев.
- Улучшение производительности чтения за счёт распределения нагрузки.

Проблема N+1 — это ситуация в веб-разработке и работе с базами данных, когда для получения связанных данных выполняется 1 запрос для основного объекта и N дополнительных запросов для связанных объектов. Это приводит к существенному падению производительности из-за большого количества запросов.
Как избежать:
- Использовать жадную загрузку (eager loading), загружая связанные данные за 1-2 запроса с помощью JOIN или специальных методов ORM.
- Оптимизировать запросы, минимизируя вызовы к базе данных.
- Применять кеширование для часто запрашиваемых данных.
- Анализировать и профилировать запросы, выявляя и устраняя избыточные обращения к БД.

Разница между batch и stream обработкой данных:
- Batch обработка работает с большими объёмами данных, собранными за определённый период, и обрабатывает их пакетами.
- Stream обработка обрабатывает данные по одному событию или в маленьких порциях в режиме реального времени.

Когда применять:
- Batch подходит для задач с высокой задержкой, когда важна обработка большого объёма данных (например, отчёты, аналитика, бэкапы).
- Stream необходима для задач с низкой задержкой и мгновенной реакцией (например, мониторинг, обработка событий, финансовые транзакции).

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

Основные типы индексов:
- BTREE — самый распространённый, подходит для точного и диапазонного поиска.
- HASH — эффективен для точного поиска, но не поддерживает диапазоны.
- FULLTEXT — используется для полнотекстового поиска в текстовых данных.
- GIN и GiST — специализированные индексы в PostgreSQL для работы с массивами, JSON и геоданными.
- Композитные индексы — индексы по нескольким колонкам для оптимизации сложных запросов.

Кэширование необходимо использовать для повышения производительности и снижения нагрузки на систему.
Когда применять кэширование:
- При частом повторном доступе к одним и тем же данным или вычислениям.
- Когда время отклика должно быть минимальным.
- Чтобы уменьшить нагрузку на базу данных, внешние API или другие ресурсоёмкие компоненты.
- При масштабировании системы для более эффективного использования ресурсов.
Итог: кэширование улучшает скорость и масштабируемость, снижая задержки и издержки на обработку данных.

Клиентский кэш
- Назначение: хранение ресурсов (HTML, CSS, JS, изображения) в браузере пользователя для ускорения повторных загрузок.
- Механизм: браузер сохраняет файлы и использует заголовки кэширования (Cache-Control, ETag).
- Преимущества: уменьшает трафик и ускоряет загрузку сайта.

CDN (Content Delivery Network)
- Назначение: распределённое хранение и доставка контента через географически близкие серверы.
- Механизм: кэширование статических и динамических ресурсов в edge-серверах по всему миру.
- Преимущества: снижает задержки, увеличивает скорость загрузки и снижает нагрузку на основной сервер.

Серверный кэш (Redis/Memcached)
- Назначение: хранение часто используемых данных (результатов запросов, сессий) в памяти сервера для быстрого доступа.
- Механизм: key-value хранилища с высокой скоростью чтения/записи.
- Преимущества: уменьшает нагрузку на базу данных, ускоряет обработку запросов и повышает масштабируемость приложения.

Round Robinалгоритм, последовательно распределяющий запросы по серверам по кругу.
- Применяется при равных ресурсах серверов и однородных задачах.
- Прост в реализации, не учитывает загрузку сервера.

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

Hash-basedиспользует хеш-функцию для распределения запросов по серверам на основе данных клиента (IP, сессия и др.).
- Эффективен при необходимости "прилипчивости" (sticky sessions).
- Обеспечивает консистентное распределение одного клиента на один сервер.

Nginx — это высокопроизводительный веб-сервер и обратный прокси-сервер, который используется для обработки HTTP-запросов, балансировки нагрузки и кэширования.
HAProxy — это надежный программный балансировщик нагрузки и прокси, специализирующийся на распределении TCP и HTTP трафика между серверами для обеспечения высокой доступности и масштабируемости.
ELB (Elastic Load Balancer) — это управляемый балансировщик нагрузки от AWS, который автоматически распределяет входящий трафик между несколькими экземплярами в облаке для повышения отказоустойчивости и производительности.

Роль в инфраструктуре:
- Распределение нагрузки между серверами для оптимального использования ресурсов
- Повышение доступности сервисов за счёт отказоустойчивых архитектур
- Улучшение производительности путём кэширования и оптимизации обработки запросов
- Обеспечение безопасности через SSL-терминацию и контроль доступа

Health checks — это механизмы мониторинга состояния сервисов или компонентов системы.
Назначение:
- Обнаружение сбоев для быстрого реагирования.
- Автоматическое масштабирование и распределение нагрузки.
- Обеспечение высокой доступности и устойчивости.
- Поддержка процессов DevOps и CI/CD через интеграцию с оркестраторами.
Таким образом, health checks позволяют вовремя выявлять проблемы и повышать надёжность систем.

Race conditions — это ситуации, когда несколько процессов или потоков одновременно обращаются к общему ресурсу без должной синхронизации, что приводит к непредсказуемому результату.
Lost updates возникают, когда параллельные операции записи перезаписывают друг друга, из-за чего часть данных теряется.

Основные причины:
- Отсутствие атомарности операций
- Недостаточная изоляция транзакций
- Отсутствие механизмов блокировки или контроля версий

Как избежать:
- Использовать механизмы блокировок (локи, мьютексы) для синхронизации доступа
- Применять транзакции с правильным уровнем изоляции (например, сериализация)
- Использовать Optimistic Concurrency Control с проверкой версии данных (например, ETags)
- Применять идемпотентные операции, снижающие последствия повторных обновлений
- Применять распределённые алгоритмы согласования (например, Two-Phase Commit, Paxos)

Итог: Для предотвращения race conditions и lost updates в распределённых системах важна правильная синхронизация, контроль версий и использование надёжных протоколов согласования.

Eventual consistency — это модель согласованности данных в распределённых системах, при которой все реплики данных в конечном итоге станут одинаковыми, но промежуточно могут отличаться. Это означает, что после обновления данных изменения распространяются асинхронно, и некоторый промежуток времени системы могут выдавать разные значения.

Когда оправдано использование eventual consistency:
- В распределённых системах с высокой нагрузкой и большими объёмами данных
- В системах с географически распределёнными кластерами для минимизации задержек
- В приложениях, где допустима временная рассогласованность (например, социальные сети, кэширование, системы рекомендаций)
- Для повышения доступности и отказоустойчивости, следуя принципам CAP-теоремы (trade-off между согласованностью и доступностью)

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

ACID и BASE — две модели управления данными в распределённых системах и базах данных.

ACID:
- Атомарность (Atomicity): операция выполняется полностью или не выполняется вовсе
- Согласованность (Consistency): переход из одного допустимого состояния данных в другое
- Изолированность (Isolation): транзакции не влияют друг на друга
- Долговечность (Durability): после подтверждения изменений данные сохраняются навсегда

Применяется в системах, где важна строгая целостность данных: банковские системы, финансовые приложения, классические реляционные СУБД.

BASE:
- Базовое состояние (Basically Available): система всегда доступна для запросов
- Мягкая согласованность (Soft state): состояние системы может быть временно несогласованным
- В конечном итоге согласованность (Eventual consistency): все узлы рано или поздно придут к одному состоянию

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

Итог:
ACID — для строгой согласованности и надежности на уровне одной транзакции.
BASE — для масштабируемости, высокой доступности и устойчивости в распределённых системах с допустимым рассогласованием.

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

Уровни изоляции транзакций определяют степень взаимодействия параллельных транзакций и контролируют вероятность аномалий:

- READ UNCOMMITTED: чтение незафиксированных изменений, максимально высокая конкуренция, возможны грязные чтения.
- READ COMMITTED: чтение только зафиксированных данных, предотвращаются грязные чтения, возможны неповторяющиеся чтения.
- REPEATABLE READ: гарантируется повторяемое чтение одних и тех же данных в транзакции, предотвращая неповторяющиеся чтения, но возможны фантомы.
- SERIALIZABLE: самый строгий уровень, транзакции исполняются последовательно, полностью устраняя фантомы и обеспечивая максимальную изоляцию.

MVCC обычно реализует уровни READ COMMITTED и REPEATABLE READ без блокировок, поддерживая баланс между производительностью и целостностью данных.

Назначение message brokers:
- Организация обмена сообщениями между системами или компонентами
- Обеспечение надёжной доставки, буферизации и маршрутизации данных
- Декуплирование отправителей и получателей для масштабируемости и отказоустойчивости

RabbitMQ
- Очередь сообщений с поддержкой различных протоколов (AMQP, MQTT и др.)
- Хорошо подходит для асинхронных задач и микросервисов с гарантированной доставкой
- Поддержка сложной маршрутизации сообщений через обменники (exchanges)
- Фокус на надежность, подтверждения и порядок сообщений внутри очереди

Kafka
- Распределённый стриминговый платформенный брокер с хранением данных в виде журналов (логов)
- Оптимален для обработки больших потоков данных в реальном времени и аналитики
- Высокая пропускная способность и масштабируемость
- Сообщения сохраняются на диске и могут повторно потребляться разными потребителями

SQS (AWS Simple Queue Service)
- Облачный управляемый сервис очередей от AWS
- Обеспечивает масштабируемость, отказоустойчивость без администрирования
- Поддерживает стандартные очереди (с возможными дублированными сообщениями) и FIFO-очереди (с гарантией порядка)
- Интеграция с другими сервисами AWS, простота использования

Ключевые отличия:
- RabbitMQ больше ориентирован на сложную маршрутизацию и гарантии доставки
- Kafka предназначен для высокопроизводительной потоковой обработки и хранения сообщений
- SQS — облачный сервис с минимальными усилиями по управлению и масштабированию

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

Преимущества:
- Асинхронность: позволяет не ждать завершения долгих операций, улучшая отзывчивость приложения.
- Масштабируемость: можно добавлять больше воркеров для ускорения обработки.
- Разгрузка основного потока: уменьшает нагрузку на веб-сервер или UI.
- Повышение надежности: задачи можно повторно ставить в очередь при ошибках.
- Гибкость: задачи могут выполняться с разной приоритетностью и расписанием.

Retrying — это механизм повторных попыток выполнения операции или запроса при временных ошибках или сбоях. Он помогает повысить надёжность систем, автоматически повторяя неудачные задачи с определённой логикой (кол-во попыток, интервалы, экспоненциальная задержка).
Dead Letter Queue (DLQ) — это специальная очередь сообщений, куда попадают задачи или сообщения, которые не удалось обработать после всех попыток retrying. Она служит для диагностики и ручной обработки ошибок.

Как работать с ними:
- При ошибке отправлять задачу на retrying с ограничением по количеству попыток и задержками
- Если max попыток исчерпаны, перемещать задачу в DLQ
- Мониторить DLQ для выявления проблем и устранения причин сбоев
- Использовать DLQ для анализа и коррекции данных или логики обработки

Таким образом, retrying повышает устойчивость системы, а DLQ обеспечивает контроль и диагностику ошибок.

Replication – это процесс копирования данных с одного узла системы на другие для обеспечения их актуальности и доступности. Цель – избежать потери данных и обеспечить непрерывность работы при сбое основного узла.
Failover – автоматическое переключение с вышедшего из строя основного узла на резервный. Обеспечивает минимальное время простоя и непрерывность сервиса.
Heartbeats – периодические сигналы (пакеты) между узлами кластера, которые проверяют их работоспособность. Отсутствие сигнала служит триггером для failover.

Паттерн Circuit Breakerмеханизм защиты системы от повторных неудачных вызовов внешних сервисов, который разрывает цепь запросов при обнаружении частых ошибок и восстанавливается после определённого времени.
Паттерн Retryстратегия повторных попыток выполнения операции при временных ошибках с контролем количества попыток и задержек между ними для повышения шансов успешного завершения.
Паттерн Timeoutограничение времени ожидания ответа от операции или сервиса, предотвращающее долгие блокировки и позволяющее системе быстрее реагировать на проблемы.
Все три паттерна совместно повышают устойчивость системы, минимизируя влияние временных сбоев и снижая нагрузку на компоненты.

Backpressure — это механизм управления нагрузкой в потоковых системах, который предотвращает переполнение и потерю данных, заставляя источник данных замедлять или приостанавливать передачу, если потребитель не успевает обрабатывать поток.
Реализация backpressure в потоковых системах:
- Буферизация: временное хранение данных в ограниченном буфере до их обработки; при переполнении буфера источник замедляется или блокируется.
- Сигналы контроля потока: потребитель информирует источник о своей текущей пропускной способности (например, запрос N элементов).
- Реактивные потоки (Reactive Streams): используют стандартные интерфейсы, где подписчик контролирует скорость получения данных через метод request(n).
- Использование очередей с ограничением размера: источник ждёт освобождения места в очереди.
Таким образом, backpressure позволяет достичь устойчивости системы и эффективного распределения ресурсов при асинхронной обработке данных.

Использование HTTPS и TLS важно для обеспечения безопасности передачи данных в интернете.
Почему важно:
- Защита данных от перехвата и подслушивания.
- Гарантия подлинности веб-сайта, предотвращающая атаки «человек посередине».
- Обеспечение целостности данных, исключая их изменение при передаче.

Как они обеспечивают безопасность:
- TLS (Transport Layer Security) устанавливает зашифрованное соединение между клиентом и сервером.
- HTTPS — это HTTP поверх TLS, обеспечивающий безопасную передачу веб-страниц.
- Используется симметричное и асимметричное шифрование для защиты данных и обмен ключами.
- Цифровые сертификаты подтверждают идентичность сервера.

Rate limiting — это механизм, который ограничивает количество запросов к API за определённый промежуток времени. Он предотвращает перегрузку сервера и защищает от злоупотреблений, таких как DDoS-атаки или чрезмерное использование ресурсов.

Реализация rate limiting на уровне API:
- Определить лимит: например, 100 запросов в минуту на одного пользователя или IP.
- Отслеживать запросы: хранить счётчик запросов для каждого клиента (по API ключу, IP или пользователю).
- Использовать временные окна: фиксированное окно (fixed window), скользящее окно (sliding window) или токен-бакет (token bucket).
- Возвращать ответ с ошибкой 429 (Too Many Requests), если лимит превышен.
- Интегрировать с кешем или базой данных для хранения состояния (Redis, Memcached).
- Реализовать на уровне API gateway или middleware, например, в Nginx, Kong, Express.js.

Итог: rate limiting обеспечивает стабильность и безопасность API, регулируя нагрузку и предотвращая злоупотребления.

CORS (Cross-Origin Resource Sharing): Угроза: некорректная настройка позволяет злоумышленникам выполнять запросы к API с чужих доменов. Защита: правильно настроить заголовки Access-Control-Allow-Origin, использовать проверку источника и аутентификацию.

CSRF (Cross-Site Request Forgery): Угроза: злоумышленник заставляет пользователя выполнить нежелательные запросы от его имени. Защита: использовать токены CSRF, проверять origin и referer, применять методы POST только для изменений.

XSS (Cross-Site Scripting): Угроза: внедрение вредоносного скрипта в веб-страницу, выполняющегося у пользователя. Защита: экранировать и фильтровать вводимые данные, использовать Content Security Policy (CSP), избегать вставки небезопасного HTML.

SQL Injection: Угроза: внедрение в SQL-запрос вредоносного кода, позволяющего получить несанкционированный доступ к базе. Защита: использовать параметризованные запросы (prepared statements), ORM, фильтрацию и валидацию входных данных.

Prometheus используется для сбора и хранения метрических данных с систем и приложений, обеспечивая мощный язык запросов для анализа показателей во времени.
Grafana служит для визуализации данных из различных источников (включая Prometheus и ELK), позволяя создавать информативные и настраиваемые дашборды.
ELK Stack (Elasticsearch, Logstash, Kibana) применяется для сбора, обработки и анализа логов, обеспечивая полнотекстовый поиск и визуализацию событий в реальном времени.

Трассировка (tracing) в распределённых системах — это метод мониторинга и анализа, позволяющий отслеживать поток запросов через несколько сервисов или компонентов. Цель трассировки — выявить задержки, ошибки и узкие места в сложных распределённых архитектурах, обеспечивая видимость взаимодействий между сервисами.

Основные понятия трассировки:
- Спан (span) — отдельный промежуток работы или операция внутри одного сервиса.
- Трейс (trace) — полная цепочка спанов, отражающая путь одного запроса через все сервисы.

Примеры инструментов:
- OpenTelemetry — открытый стандарт и набор SDK для сборки, передачи и анализа телеметрии (трейсов, метрик, логов) из приложений. Позволяет разработчикам легко внедрять трассировку и интегрируется с разными бекенд-системами.
- Jaeger — система для сбора, хранения и визуализации трасс, которая часто используется совместно с OpenTelemetry. Помогает находить причины задержек, анализировать производительность и улучшать архитектуру распределённых систем.

Определения метрик SLA, SLO, SLI:
- SLA (Service Level Agreement) — формальное соглашение между поставщиком услуги и клиентом, описывающее ожидаемый уровень сервиса.
- SLO (Service Level Objective) — конкретные цели по качеству сервиса (например, доступность 99.9%), на основе которых измеряется выполнение SLA.
- SLI (Service Level Indicator) — конкретные показатели (метрики), отражающие фактическое качество сервиса (например, время отклика, процент успешных запросов).

Использование метрик:
- SLI собираются постоянно для оценки текущего состояния сервиса.
- SLO устанавливают целевые значения для этих метрик.
- SLA определяет ответственность и последствия при несоблюдении SLO.
- Эти метрики помогают мониторить, управлять качеством сервиса и взаимодействием с клиентом.

Значение health checks:
- Health checks — автоматизированные проверки состояния компонентов системы.
- Они позволяют быстро выявлять неисправности и снижать время простоя.
- Важны для поддержания высокой доступности и выполнения SLO, так как дают оперативную информацию о работоспособности сервиса.
- Используются в балансировщиках нагрузки и оркестраторах для маршрутизации трафика и перезапуска сбойных сервисов.

Optimistic locking – это подход к управлению конкуренцией при доступе к данным, при котором предполагается, что конфликты редки. Изменения записываются без блокировок, но перед сохранением проверяется, не изменился ли объект с момента чтения. Если изменения обнаружены, операция откатывается.

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

Когда применять:
- Optimistic locking подходит для систем с низкой частотой конфликтов и высокой нагрузкой, где важно избежать блокировок и повысить производительность.
- Pessimistic locking уместен в системах с высокой конкуренцией за ресурсы, где данные должны быть строго согласованы.

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