Архитектура web-приложений, или куда могут расти в приложения

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

Мы применяем два подхода к реализации приложений: монолитные приложения и микросервисная архитектура.

Монолитное приложения — это когда приложение сделано под девизом «всё в одном», то есть когда фронтенд и бэкенд едины. Например, приложение без какого-либо API либо Laravel на Blade-шаблонах. То есть это приложение выгружается одновременно: и фронтенд, и бэкенд в одной папочке. Это имеет как плюсы, так и минусы в процессе работы.

Микросервисная архитектура — это когда есть источник данных (в виде API, либо других систем: GraphQL, JSON API и так далее) и какие-либо клиенты (это может быть мобильное приложение, фронтенд на API, на React, на Vue.js и так далее). Либо это какие-то дополнительные системы, например, 1C, которая может взаимодействовать с интернет-магазином, либо какая-то очередь, как GraphQL.

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

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

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

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

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

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

Как можно развивать приложение дальше? Можно перенести в облако нашу базу данных и кэш. Таким образом, наше приложение на VPS/VDS начинает тратить очень мало времени, так как занимается обработкой только итоговых результатов. Оно обращается отдельно к хранилищу с кэшем, и к хранилищу с базой данных, которые могут обслуживать Яндекс или Amazon.

Дальше у нас становится очень много пользователей, и наше приложение, которое хранится на одном сервере, не успевает обрабатывать все данные. Что мы делаем в этом случае? Берём несколько небольшихсерверов, которые объединяются через балансировщик нагрузки. Балансировщик распределяет нагрузку от наших пользователей на несколько серверов. Благодаря этому мы можем не брать огромные по мощности истоимости сервера — то есть будем экономить деньги клиенту. А за счёт балансировки мы сможем спокойно обслуживать большой парк компьютеров. При этом остальная архитектура останется в том же самом виде.

Далее можно подключить обработку каких-то сложных вопросов. Частый кейс: мы загружаем какое-то изображение или видео в разрешении 4K, и нам нужно нужно сделать их пререндер. Мы хотим получить несколько разных разрешений, но в моменте этого сделать нельзя из-за процессорного времени.

В этом случае очень часто применяются очереди. Итак, картинка загрузилось на S3 Cloud. Дальше создаётся задача через какое-то время обработать эту картинку. У «Ракетной» был проект «Медиахаб», который как раз делал что-то подобное. На первоначальном этапе текущие сервера с приложениями в состоянии обслуживать эту задачу. Единственное, нужно будет между ними распределить задачи: какие-то будет делать один сервер,какие-то — другой. Под понятием очереди мы понимаем разные ситуации. Например, нам нужно, чтобыэлектронная почта отправлялась не моментально, а вставала в очередь. Так, если 100500 пользователейрегистрируется в приложении, почтовый сервер не отключит нас за то, что мы ему послали единовременно такмного задач.

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

В завершение скажем про важный момент, который можно подключить как на начальном этапе развития приложения, так и в дальнейшем — поисковые движки, которые рано или поздно понадобятся пользователям. На начальном этапе их можно размещать на том же самом сервере, но в дальнейшем придётся переносить, потому что поисковые движки очень требовательны и к оперативный памяти, и к серверному пространству,поэтому их тоже можно использовать либо на отдельном сервисе, либо на отдельной VDS-ке. У «Ракетной» есть несколько примеров таких проектов. Например, для «Медиахаба» и «Апотеки» поисковые движки на Elasticsearch были вынесены отдельно.