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

Для вашего следующего продукта/проекта я предлагаю архитектуру, где я собрал относительно новые или действительно новые, но в то же время проверенные технологии с их лучшими наработками. Вот как это выглядит 👇. (И обратите внимание, это можно сделать, используя только один язык — Javascript)

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

Начнем с

Серверная часть

Node.js

Здесь я использую Node.js, потому что это моя любимая среда выполнения, вы можете использовать ту, которая вам удобна. Node.js работает совсем иначе, чем другие, в зависимости от случая это может быть выгодно или наоборот. Огромные компании не используют Node.js для всей своей бизнес-логики, но они могут использовать его частично для решения конкретной проблемы, поэтому Node в наши дни чрезвычайно популярен.
Самое главное здесь то, что вам нужна ваша поддержка. -конец времени выполнения, чтобы быть без гражданства. Это важно для масштабируемости. Например, вы не должны хранить или кэшировать какие-либо данные в своем серверном приложении, сеанс аутентификации пользователя — лучший пример таких данных, что недопустимо. Вместо этого вы можете использовать Redis для хранения пользовательских сеансов или использовать JWT. Когда ваш внутренний сервер не имеет состояния, вы готовы к горизонтальному масштабированию.

MongoDB

Это база данных NoSQL, лучшая в своем роде. Вопрос «SQL или NoSQL». Что ж, если вы не строите следующую многомиллиардную компанию, вам подойдет любой из этих двух. Но это не значит, что вы можете закрыть вопрос и остановиться на одном. У каждого есть свои плюсы и минусы, каждый решает конкретную проблему лучше, чем другой. Если вы все еще читаете этот абзац, рекомендую хотя бы углубиться в подробности, погуглив.

Наши экземпляры Node.js подключены к MongoDB. Кроме того, мы используем преимущества баз данных в памяти (например, Redis) и осуществляем перехват между внутренними запросами и MongoDB. (Примечание. Не следует использовать Redis для каждой службы, которая запрашивает данные, вместо этого вы можете использовать его для данных, которые часто запрашиваются и редко обновляются).

Редис

Это хранящаяся в памяти база данных «ключ-значение». В основном он используется для хранения временных данных (для кэширования) для более быстрого доступа. Также для любых данных, которые вам нужно извлечь из вашего приложения среды выполнения, чтобы иметь приложение без сохранения состояния. Используя такую ​​технологию, мы также сокращаем количество запросов к нашей базе данных MongoDB.

Когда наше приложение Node.js запрашивает данные, мы сначала проверяем, кэшируются ли они в Redis, если ответ да — Redis возвращает данные, если нет — Redis позволяет запросу достичь MongoDB, а затем сохраняет копию данные для следующего раза (будущий запрос, который запрашивает те же данные). Наше приложение Node.js также может аннулировать часть кеша Redis при обновлении определенных данных в MongoDB.

Рабочий

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

ГрафQL

GraphQL — очень популярная технология для клиент-серверных коммуникаций. Он был разработан Facebook в 2012 году и стал открытым исходным кодом в 2015 году. С 2015 года за очень короткий период времени он стал любимой технологией для многих разработчиков. Многие ведущие компании, такие как Facebook, Github, Airbnb, используют GrahQL. Вместо традиционных REST API, в которых на фронтенде вы взаимодействуете с уже подготовленными полями данных, используя разные конечные точки, в GraphQL у вас есть одна конечная точка, и вы сами решаете, какие поля вам нужны для конкретного запроса.

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

Веб-сервисы Amazon (AWS)

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

АВС S3

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

Мы не делаем наши корзины s3 общедоступными, вместо этого мы используем CDN (сеть доставки контента) для обслуживания данных из S3. Мы также можем воспользоваться событиями S3 и запустить Lambdas.

АВС Лямбда

AWS Lambda (так называемые бессерверные функции) — это вычислительная служба. Подумайте о коротко работающем сервере, вот его жизненный цикл: что-то запускает лямбда-функцию, экземпляр вашей лямбда-функции запускается немедленно, выполняет свою работу и исчезает. И вы платите только за время его работы. Lambda не зависит от языка, поэтому вы можете запускать код node.js, python, ruby, go, java и т. д. Вы можете активировать функцию Lambda сервисом AWS, например API Gateway, и использовать свою лямбду в качестве контроллера конечной точки или сервера бизнес-логики. Вы можете использовать любой сервис AWS в своей лямбда-функции, вы также можете добавлять собственные слои. Так что это очень мощный сервис.
Мы используем Lambdas для преобразования видео, создавая задания на преобразование и запуская его с помощью корзины s3 при загрузке нового видео. Также для пользовательских аватаров, чтобы создавать аватары разных размеров. Мы записываем данные в нашу DynamoDB, также отправляем запрос на вебхуки нашего основного сервера для передачи некоторых данных или сообщаем об успехе/неуспехе.

AWS DynamoDB

Это система баз данных NoSQL от AWS, ее можно использовать практически для всего (например, для вашего бизнес-уровня).
Мы используем ее для обработки данных в облаке. Например, мы конвертируем видео с помощью лямбда-выражений и сервиса AWS MediaConvert, записываем в DynamoDB данные анализа файлов, результаты обработки и другую полезную информацию во время выполнения. DynamoDB в целом очень мощный. Если вы используете AWS, я рекомендую ознакомиться с его функциями и вариантами использования.

AWS CloudFront

Это CDN AWS, который работает очень быстро. Он имеет более 225 точек по всему миру.

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

Внешний интерфейс

Реагировать

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

Мы используем Create-React-App для рендеринга приложений на стороне клиента и Next.js, если нам нужен рендеринг на стороне сервера. Оба являются очень популярными и последовательными фреймворками, построенными поверх React.

клиент Аполлона

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

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

Редукс

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

Мы используем его только для состояния пользовательского интерфейса, поскольку мы используем GraphQL, мы считаем, что клиент Apollo более предпочтителен для управления данными и кэширования. Но если вы используете REST для выборки данных, вы также можете использовать Redux для управления данными.

Это все для конкретных единиц нашей архитектуры. Теперь давайте посмотрим на более широкую картину.

Большая картинка

Сторона клиента

Когда пользователь открывает наш веб-сайт, он/она запрашивает файл index.html из нашей CDN. Файл index.html содержит все необходимые ресурсы для работы нашего веб-приложения, в частности наш пакет javascript (или фрагменты), который также загружается из CDN в браузер пользователя. , а затем выполняется. Сам пакет представляет собой наше Reactвеб-приложение, транскомпилированное в кросс-браузерный javascript с помощью Babel и объединенное с помощью Webpack. После выполнения код Apollo GraphQL извлекает необходимые данные, кэширует их в памяти пользовательского устройства и обновляет пользовательский интерфейс приложения (перерисовывает HTML-код, чтобы отразить новое состояние). Это краткое описание того, что происходит под капотом приложения React, отображаемого на стороне клиента с использованием Create-React-App.

Сторона сервера

Теперь давайте посмотрим, как поток данных извлекается клиентом Apollo. Клиент Apollo отправляет GraphQL-запрос к слою GraphQL нашего внутреннего сервера, который разрешает его, сообщая с нашим сервером Node.js. Сервер Node.js соответственно запрашивает данные у БД. Здесь Redis входит и проверяет, есть ли такой запрос в кеше, и решает, следует ли вернуть данные или передать запрос в MongoDB. После операций с БД Node.js получает данные и отправляет их клиенту через GraphQL-сервер.

Теперь давайте посмотрим на наши сервисы AWS в действии.

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

Поскольку пользователь выбрал видео, наше клиентское приложение отправляет метаданные на наш сервер Node.js. Сервер Node.js принимает метаданные, подключается к AWS S3 и запрашивает конечную точку (подписанный URL-адрес) для загрузки определенного файла. Как только Node.js получает URL (конечная точка загрузки), он отвечает на запрос клиента. Теперь мы можем сказать, что Node.js закончил загрузку.

Теперь настала очередь клиента выполнить задание, поэтому клиент начинает загрузку непосредственно в AWS S3 через подписанный URL-адрес. После завершения загрузки S3 может запустить функцию Lambda, чтобы уведомить сервер Node.js о том, что у нас есть новое видео. Node.js создает новую запись в MongoDB, сохраняя ссылку на видео. Другая Lambda может выполнять задание по преобразованию видео и генерировать это видео в различных форматах или качествах.

Итак, все быстро и без проблем, все довольны.

Вывод

Эта архитектура не самая сложная. Но этого достаточно, чтобы на какое-то время хватило для большинства продуктов/бизнесов. Его можно очень хорошо масштабировать и легко расширять в контексте функций. Эти два выше очень-очень важны. В зависимости от сложности вашего продукта, от потребностей бизнеса и т. д., вы можете упростить его и пропустить какой-либо блок этой архитектуры, и, конечно же, прочитать о принципе KISS :)

Спасибо за чтение. Я собираюсь публиковать больше историй о разных архитектурах, следите за мной на Medium.

Мой гитхаб: https://github.com/JeDaVard