Разработка надёжной, масштабируемой и эффективной системы может оказаться довольно сложным делом. Однако понимание основных принципов и компонентов этого процесса может сделать его более управляемым. В статье рассмотрим основные компоненты в проектировании систем: DNS, балансировка нагрузки, API-шлюз и другие. Также предоставим краткую схему, которая поможет разработчикам проектировать системы разной сложности.
Содержание:
Схема проектирования системы
А вот наглядная схема.
С ней разработчик всегда сможет быстро освежить в памяти ключевые принципы и методы проектирования систем. Схема охватывает такие темы, как DNS, балансировка нагрузки, API-шлюз, обработка видео и изображений, кэширование, базы данных, генерация уникальных идентификаторов.
Также указаны стандартные компоненты системы, такие как сервисы платежей и рекомендаций, протоколы чата и потоковой передачи данных. Имея под рукой эту схему, вам будет проще проектировать и внедрять масштабируемые, эффективные и надежные системы.
Раздел 1: Принципы проектирования систем
1.1: Модульность
Разделение системы на более мелкие, управляемые модули помогает снизить ее сложность, улучшить удобство обслуживания и возможности повторного использования.
1.2: Абстракция
Чтобы упростить сложные системы, можно скрыть подробности их реализации и демонстрировать только основные функции. Такой подход также способствует модульности.
1.3: Разбиение на слои
Распределение системы по слоям, каждый из которых содержит определенный набор функций, помогает адресно работать с проблемами и улучшает удобство обслуживания.
1.4: Масштабируемость
Проектирование системы с учетом возрастания нагрузки на нее. С возросшей нагрузкой можно справляться добавлением дополнительных ресурсов (горизонтальное масштабирование) или оптимизацией мощности системы (вертикальное масштабирование).
1.5: Производительность
Оптимизация времени отклика, пропускной способности и использования ресурсов — все это важно учитывать для проектирования эффективной системы.
1.6: Безопасность
Чтобы обеспечить конфиденциальность, целостность и доступность системы, нужно внедрять соответствующие инструменты обеспечения безопасности.
1.7: Отказоустойчивость и способность к восстановлению
Проектирование систем, которые устойчивы к сбоям и могут восстанавливаться после ошибок.
Раздел 2: Ключевые компоненты проектирования систем
2.1: DNS (система доменных имен)
DNS — это иерархическая и децентрализованная система именования компьютеров, сервисов или других ресурсов, подключенных к Интернету или частной сети. Она переводит понятные человеку доменные имена (например, www.example.com) в IP-адреса, делая доступ к веб-сайтам и сервисам более удобным.
2.2: Балансировка нагрузки
Балансировка нагрузки — это распределение сетевого трафика между несколькими серверами, чтобы ни один не был перегружен. Такой подход повышает доступность, надежность и производительность системы. Примеры стандартных алгоритмов балансировки нагрузки — Round Robin, Least Connections и IP Hash.
2.3: API-шлюз
API-шлюз — это сервер-посредник между клиентами и микросервисами в распределенной системе. Он управляет запросами и маршрутизирует их, обеспечивает соблюдение политик безопасности, а также может предоставлять дополнительные функции, такие как кэширование, ведение журнала и мониторинг.
2.4: Сеть доставки контента (CDN)
CDN — это распределенная по разным локациям сеть серверов. С ее помощью пользователи получают контент с меньшей задержкой и большей пропускной способностью. CDN кэширует контент на периферийных серверах, которые находятся близко к конечным пользователям. Эта сеть повышает производительность системы и снижает нагрузку на сервер-источник.
2.5: Очередь сообщений
Сообщения временно хранятся в очереди, чтобы облегчить взаимодействие между компонентами распределенной системы. Также эта очередь обеспечивает асинхронную обработку компонентов и помогает разделять их. Это позволяет улучшить масштабируемость и отказоустойчивость системы.
Подробнее: Все о распределённой очереди сообщений
Everything about Distributed Message Queue
2.6: Коммуникационные протоколы
При разработке систем используются различные коммуникационные протоколы, такие как HTTP/HTTPS, WebSocket и gRPC. У каждого из них есть свои преимущества и недостатки. Поэтому при выборе нужно учитывать важные для вас моменты, такие как задержка, безопасность и требования к передаче данных.
2.7: Кэш
Кэширование — это метод временного хранения копий данных. Он позволяет быстрее находить эти данные при последующих запросах. Кэширование помогает снизить задержку, нагрузку на сервер и потребление полосы пропускания. Примеры популярных подходов в этой области включают кэширование в памяти, распределенное и браузерное кэширование.
2.8: База данных
Выбор подходящей базы данных для системы зависит от таких факторов, как структура, масштабируемость и согласованность данных, а также задержка в доступе к ним. К распространенным типам решений относятся реляционные базы данных (например, MySQL, PostgreSQL), базы данных NoSQL (например, MongoDB, Cassandra) и базы данных NewSQL (например, Cockroach DB, Google Spanner).
2.9: Техники репликации
Репликация — это сохранение нескольких копий данных на разных узлах системы для повышения ее надежности, доступности и отказоустойчивости. Примеры стандартных подходов включают синхронную, асинхронную и полусинхронную репликацию.
2.10: Распределенная генерация уникальных идентификаторов
Создание уникальных идентификаторов в распределенной системе может быть сложной задачей, но ее нужно решить, чтобы поддерживать согласованность и целостность данных.
Раздел 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-адреса, выполните следующие действия:
Разделите файл на чанки. Разделите большой файл на мелкие фрагменты на стороне клиента. Обычно это делается с помощью JavaScript. Размер чанка может варьироваться, но для оптимальной загрузки важно добиться баланса между количеством запросов и размером каждого чанка.
Запросите подписанные URL для каждого чанка. Отправьте на ваш сервер запрос для создания подписанных URL. Сервер должен создать подписанный URL с соответствующими разрешениями и временем действия и вернуть его клиенту.
Загрузите чанки с помощью подписанных URL-адресов. Загрузите чанки в облачное хранилище. В зависимости от желаемого уровня параллелизма и условий сети эти загрузки могут выполняться последовательно или параллельно.
Подтвердите успешную загрузку и выполните сборку. Как только все чанки будут загружены, сообщите об этом серверу, чтобы подтвердить завершение загрузки. После этого сервер может собрать фрагменты в исходный файл, а также выполнить дополнительную обработку или проверку.
Обработайте неудачные загрузки. Если какой-либо чанк не будет загружен, повторите попытку, используя новый подписанный URL-адрес. Или примените свою стратегию обработки ошибок, чтобы обеспечить бесперебойную работу.
Используя подписанные URL-адреса и чанковую загрузку, разработчики могут эффективно и безопасно обрабатывать большие видео и изображения, а также повышать надежность и производительность своих систем.
Раздел 4: Протоколы чата и потоковой передачи данных
В этом разделе мы рассмотрим протоколы чата и потоковой передачи, которые обеспечивают связь в реальном времени и потоковую передачу данных между клиентами и серверами. Понимание этих протоколов поможет разработчикам создавать интерактивные и отзывчивые приложения.
4.1: RTMP (Real-Time Messaging Protocol)
RTMP — это запатентованный протокол Adobe Systems. Он нужен для потоковой передачи аудио, видео и данных через Интернет, широко используется в приложениях для потоковой передачи видео и обеспечивает низкую задержку при передаче данных между клиентами и серверами. Однако из-за зависимости от Flash Player его популярность в последние годы снизилась.
на момент перевода, 26.06.2022, 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: Служба рекомендаций
Сервисы рекомендаций показывают пользователям персонализированные предложения на основе их предпочтений, поведения и других факторов. Они могут значительно повысить вовлеченность и удовлетворенность пользователей. Методы создания рекомендаций включают коллаборативную и контентную фильтрацию, а также гибридные подходы. Для создания более сложных рекомендаций также можно использовать алгоритмы машинного обучения, такие как матричная факторизация и глубокое обучение.
Включая эти стандартные компоненты в свои системы, разработчики могут повысить функциональность приложений и улучшить клиентский опыт.
Раздел 6: Передовые практики системного проектирования
6.1: Сбор требований
Тщательно изучите и задокументируйте требования к системе перед началом проектирования.
6.2: Шаблоны проектирования
Используйте проверенные шаблоны для решения повторяющихся проблем и улучшения общей архитектуры.
6.3: Документация
Документируйте свои решения, предположения и обоснования в рамках проекта, чтобы улучшить взаимодействие с заинтересованными сторонами и повысить удобство обслуживания системы.
6.4: Итеративное проектирование
Доработайте свой проект в рамках нескольких итераций и циклов обратной связи. Позвольте ему расти и развиваться.
6.5: Тестирование и валидация
Проверьте соответствие вашего проекта требованиям и проведите тестирование для выявления и устранения потенциальных проблем.
Заключение
Проектирование системы — многогранный и сложный процесс, требующий глубокого понимания разных компонентов, протоколов и методов. В статье мы рассмотрели такие темы, как DNS, балансировка нагрузки, API-шлюзы, обработка видео и изображений, кэширование, базы данных, генерация уникальных идентификаторов, стандартные компоненты, такие как сервисы платежей и рекомендаций, а также протоколы чата и потоковой передачи данных.
Используя эти знания, разработчики могут создавать масштабируемые, эффективные и надежные системы, которые отвечают поставленным требованиям и обеспечивают бесперебойную работу пользователей. Важно помнить, что проектирование системы — итерационный процесс, и для создания и поддержки успешных приложений нужно постоянное совершенствование. Разработчик, который понимает рассмотренные выше концепции и важность адаптивности, может уверенно проектировать и внедрять надежные системы.
Перевод подготовлен KTS.
Другие наши статьи и переводы по бэкенду и асинхронному программированию для начинающих:
Цикл статей «Первые шаги в aiohttp»: пишем первое hello-world-приложение, подключаем базу данных, выкладываем проект в Интернет
Другие наши статьи по бэкенду и асинхронному программированию для продвинутого уровня: