[Перевод] Полное руководство по проектированию систем в виде схемы

ed0caab71272a70f7906e3ec0ae2a053.jpg

Разработка надёжной, масштабируемой и эффективной системы может оказаться довольно сложным делом. Однако понимание основных принципов и компонентов этого процесса может сделать его более управляемым. В статье рассмотрим основные компоненты в проектировании систем: DNS, балансировка нагрузки, API-шлюз и другие. Также предоставим краткую схему, которая поможет разработчикам проектировать системы разной сложности.

Содержание:

  1. Схема проектирования системы

  2. Принципы проектирования систем

    1. Модульность

    2. Абстракция

    3. Разбиение на слои

    4. Масштабируемость

    5. Производительность

    6. Безопасность

    7. Отказоустойчивость и способность к восстановлению

  3. Ключевые компоненты проектирования систем

    1. DNS (система доменных имен)

    2. Балансировка нагрузки

    3. API-шлюз

    4. Сеть доставки контента (CDN)

    5. Очередь сообщений

    6. Коммуникационные протоколы

    7. Кэш

    8. База данных

    9. Техники репликации

    10. Распределенная генерация уникальных идентификаторов

  4. Загрузка видео и изображений по чанкам с помощью подписанных URL-адресов

    1. Что такое подписанные URL-адреса?

    2. Чанковая загрузка

    3. Комбинирование подписанных URL-адресов и чанковой загрузки

  5. Протоколы чата и потоковой передачи данных

    1. RTMP (Real-Time Messaging Protocol)

    2. WebRTC (Web Real-Time Communication)

    3. WebSocket

    4. SSE (Server-Sent Events)

    5. HTTP Short Polling

    6. HTTP Long Polling

    7. Вебхуки

    8. Stream API

  6. Стандартные компоненты при проектировании системы

    1. Платежный сервис

    2. Сервис аналитики

    3. Сервисы уведомлений

    4. Поисковые сервисы

    5. Служба рекомендаций

  7. Передовые практики системного проектирования

    1. Сбор требований

    2. Шаблоны проектирования

    3. Документация

    4. Итеративное проектирование

    5. Тестирование и валидация

  8. Заключение

Схема проектирования системы

А вот наглядная схема.

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

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

be60f2a8e27fc96692f1e4e345c9fb10.jpg

Ссылка на полное изображение

Раздел 1: Принципы проектирования систем

1.1: Модульность

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

1.2: Абстракция

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

1.3: Разбиение на слои

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

1.4: Масштабируемость

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

1.5: Производительность

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

1.6: Безопасность

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

1.7: Отказоустойчивость и способность к восстановлению

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

Раздел 2: Ключевые компоненты проектирования систем

2.1: DNS (система доменных имен)

DNS — это иерархическая и децентрализованная система именования компьютеров, сервисов или других ресурсов, подключенных к Интернету или частной сети. Она переводит понятные человеку доменные имена (например, www.example.com) в IP-адреса, делая доступ к веб-сайтам и сервисам более удобным.

Подробнее: Масштабирование приложений за счет оптимизации конфигурации DNS
Scale Applications by optimizing DNS Configuration

d303ce94bf3126c146125d830122b691.jpg

2.2: Балансировка нагрузки

Балансировка нагрузки — это распределение сетевого трафика между несколькими серверами, чтобы ни один не был перегружен. Такой подход повышает доступность, надежность и производительность системы. Примеры стандартных алгоритмов балансировки нагрузки — Round Robin, Least Connections и IP Hash.

Подробнее: Всё о балансировщике нагрузки с Cheat Sheet
Everything about Load Balancer with Cheat Sheet

2.3: API-шлюз

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

2.4: Сеть доставки контента (CDN)

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

Подробнее: Руководство для начинающих по CDN: что это такое и как это работает
A Beginner«s Guide to CDN: What it is and How it Works

2.5: Очередь сообщений

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

Подробнее: Все о распределённой очереди сообщений
Everything about Distributed Message Queue

2.6: Коммуникационные протоколы

При разработке систем используются различные коммуникационные протоколы, такие как HTTP/HTTPS, WebSocket и gRPC. У каждого из них есть свои преимущества и недостатки. Поэтому при выборе нужно учитывать важные для вас моменты, такие как задержка, безопасность и требования к передаче данных.

2.7: Кэш

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

Подробнее: Полное руководство по распределенному кэшированию
A Comprehensive Guide to Distributed Caching

2.8: База данных

Выбор подходящей базы данных для системы зависит от таких факторов, как структура, масштабируемость и согласованность данных, а также задержка в доступе к ним. К распространенным типам решений относятся реляционные базы данных (например, MySQL, PostgreSQL), базы данных NoSQL (например, MongoDB, Cassandra) и базы данных NewSQL (например, Cockroach DB, Google Spanner).

2.9: Техники репликации

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

2.10: Распределенная генерация уникальных идентификаторов

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

Подробнее: 7 известных подходов к созданию распределенного ID со сравнительной таблицей
7 Famous Approaches to Generate Distributed ID with Comparison Table

Раздел 3: загрузка видео и изображений по чанкам с помощью подписанных URL-адресов

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

3.1: Что такое подписанные URL-адреса?

Это специальные URL-адреса, которые предоставляют временный безопасный доступ к определенному ресурсу. Например, к объекту в облачном хранилище. Эти URL содержат сигнатуру аутентификации, которая позволяет пользователю выполнить определенное действие. Например, загрузить или скачать файл в течение ограниченного периода времени. Популярные провайдеры облачных хранилищ, такие как Amazon S3 и Google Cloud Storage, позволяют создавать подписанные URL-адреса. Вот пример того, как может выглядеть подписанный URL:

https://example-bucket.s3.amazonaws.com/my-file.txt?\
  X-Amz-Algorithm=AWS4-HMAC-SHA256&
  X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20220407%2Fus-east-1%2Fs3%2Faws4_request&\
  X-Amz-Date=20220407T123456Z&\
  X-Amz-Expires=3600&\
  X-Amz-SignedHeaders=host&\
  X-Amz-Signature=a9c8a7d1644c7b351ef3034f4a1b4c9047e891c7203eb3a9f29d8c7a74676d88

3.2: Чанковая загрузка

Загрузка больших файлов за один запрос может привести к тайм-аутам, большому расходу памяти и повышенному риску сбоев из-за нестабильности сети. Чтобы решить эту проблему, большие файлы разбивают на мелкие фрагменты и загружают их последовательно или параллельно. Такой подход повышает эффективность и надежность загрузки. Он известен как «чанковая» загрузка или загрузка «по частям».

3.3: Комбинирование подписанных URL-адресов и чанковой загрузки

Чтобы загружать видео и изображения частями, используя подписанные URL-адреса, выполните следующие действия:

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

  2. Запросите подписанные URL для каждого чанка. Отправьте на ваш сервер запрос для создания подписанных URL. Сервер должен создать подписанный URL с соответствующими разрешениями и временем действия и вернуть его клиенту.

  3. Загрузите чанки с помощью подписанных URL-адресов. Загрузите чанки в облачное хранилище. В зависимости от желаемого уровня параллелизма и условий сети эти загрузки могут выполняться последовательно или параллельно.

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

  5. Обработайте неудачные загрузки. Если какой-либо чанк не будет загружен, повторите попытку, используя новый подписанный URL-адрес. Или примените свою стратегию обработки ошибок, чтобы обеспечить бесперебойную работу.

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

Раздел 4: Протоколы чата и потоковой передачи данных

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

4.1: RTMP (Real-Time Messaging Protocol)

RTMP — это запатентованный протокол Adobe Systems. Он нужен для потоковой передачи аудио, видео и данных через Интернет, широко используется в приложениях для потоковой передачи видео и обеспечивает низкую задержку при передаче данных между клиентами и серверами. Однако из-за зависимости от Flash Player его популярность в последние годы снизилась.

4.2: WebRTC (Web Real-Time Communication)

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

4.3: WebSocket

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

4.4: SSE (Server-Sent Events)

Server-Sent Events (SSE) — это технология, которая позволяет серверам получать данные о клиентских событиях через HTTP-соединение. Она предназначена для односторонней связи от сервера к клиенту в реальном времени, что делает ее подходящим решением для приложений, работающих с новостными лентами и уведомлениями.

4.5: HTTP Short Polling

В случае с Short Polling клиенты неоднократно отправляют HTTP-запросы на сервер, чтобы проверить наличие новых событий. Несмотря на простоту реализации метода, он может привести к высокой нагрузке на сервер и увеличению задержки из-за постоянных запросов, особенно если новые события происходят нечасто.

4.6: HTTP Long Polling

Это улучшенный вариант Short Polling: клиент посылает запрос на сервер, а сервер держит его открытым до получения новых данных. Такой подход снижает количество запросов и нагрузку на сервер, однако он все же может приводить к задержкам и требует тщательного управления ресурсами сервера.

4.7: Вебхуки

Вебхуки — это определяемые пользователем HTTP-коллбеки, запускаемые в результате определенных событий в системе. Когда происходит событие, сайт-источник отправляет HTTP-запрос на URL, настроенный для вебхука. Этот подход позволяет обеспечить эффективное, привязанное к событиям взаимодействие между разными системами или сервисами.

4.8: Stream API

Stream API позволяет клиентам получать непрерывный поток данных с сервера, часто с помощью соединения по HTTP или WebSocket. Эти API предназначены для приложений, которым нужно получать данные в реальном времени. Например, это актуально для лент социальных сетей, данных фондового рынка и аналитики в реальном времени.

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

Раздел 5: Стандартные компоненты при проектировании системы

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

5.1: Платежный сервис

Платежные сервисы обрабатывают транзакции между клиентами и компаниями. Для сервисов электронной коммерции и платформ, основанных на подписке, критически важно интегрировать надежный платежный сервис. Примеры популярных сервисов: Stripe, PayPal и Square. Обычно они предоставляют API для обеспечения безопасности транзакций и управления повторяющимися платежами, возвратами и т. п.

5.2: Сервис аналитики

Сервисы аналитики позволяют собирать, обрабатывать и визуализировать данные, помогая компаниям принимать взвешенные решения. Они могут отслеживать поведение пользователей, контролировать производительность системы и анализировать тенденции. Примеры таких сервисов — это Google-Analytics, Mixpanel и Amplitude. Интеграция сервисов аналитики в систему поможет компаниям оптимизировать свои предложения и улучшить клиентский опыт.

5.3: Сервисы уведомлений

Сервисы уведомлений информируют пользователей о новостях, событиях и другой важной информации. Эти сервисы могут доставлять уведомления по почте, SMS, отправлять push-уведомления.

Примеры сервисов: Firebase Cloud Messaging (FCM), Amazon Simple Notification Service (SNS) и Twilio.

5.4: Поисковые сервисы

Мощная поисковая система необходима для систем с большим объемом данных или контента. Она должна быть масштабируемой и обеспечивать быстрый и релевантный поиск. Примеры поисковых сервисов — Elasticsearch, Apache Solr и Amazon CloudSearch. Обычно они поддерживают фильтры, полнотекстовый и фасетный поиск. Это позволяет пользователям находить нужную информацию быстро и эффективно.

5.5: Служба рекомендаций

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

ae02cd3b77f163d3fb517533614b25f1.jpg

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

Раздел 6: Передовые практики системного проектирования

6.1: Сбор требований

Тщательно изучите и задокументируйте требования к системе перед началом проектирования.

6.2: Шаблоны проектирования

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

6.3: Документация

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

6.4: Итеративное проектирование

Доработайте свой проект в рамках нескольких итераций и циклов обратной связи. Позвольте ему расти и развиваться.

6.5: Тестирование и валидация

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

Заключение

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

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

Перевод подготовлен KTS.

Другие наши статьи и переводы по бэкенду и асинхронному программированию для начинающих:

Другие наши статьи по бэкенду и асинхронному программированию для продвинутого уровня:

© Habrahabr.ru