Как стать автором
Обновить

Серверная архитектура: быстрый старт проекта и его эволюционное развитие

Время на прочтение8 мин
Количество просмотров4.4K

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

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

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

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

Облака

Белогривые лошадки. Начнем с того, что не стоит самим покупать «железки» и делать свой центр обработки данных. Это сложно, долго и дорого. Лучше разместите свое приложение у облачных провайдеров, используя IaaS. Так вы сэкономите деньги, время и нервы. Свой ЦОД — это удел крупных компаний со специфическими требованиями.

В современных реалиях для российского проекта стоит выбрать отечественного облачного провайдера. Например:

Также для приценки приведу стоимость сервера:

  • Selectel (4 ядра, 8 ГБ ОЗУ и 30 ГБ на очень быстром NVMe диске):

  • Yandex.Cloud (4 ядра, 8 ГБ ОЗУ и 30 ГБ на быстром SSD диске):

Сколько серверов?

Для начала вам потребуется два сервера:

  1. Сервер тестирования (dev). На нем вы проверяете все новые фичи и исправленные баги.

  2. Сервер эксплуатации (prod). На нем и размещаете ваше приложение для пользователей.

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

  • веб-сервер, 

  • сервер системы управления базами данных,

  • почтовый сервер, 

  • все остальное, что потребуется вашему приложению. 

Со временем prod претерпит изменения. Какие? Чтобы узнать, придется читать дальше!

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

  • менее 50% своих ресурсов работает штатно.

  • 50-70% заставляет задуматься о дополнительных ресурсах.

  • 90% и более не дает вашему приложению работать от слова совсем. Это катастрофа и вы единолично вызываете глобальное потепление. Должно быть стыдно. 

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

  • скорость чтения записи на диск; 

  • ОС и ее настройки; 

  • используемая СУБД и ее настройки; 

  • используемый веб-сервер и его настройки и т. д.

Что еще вам обязательно понадобиться

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

Система контроля и управления версиями жизненно необходима! Используйте Git, достойных альтернатив попросту нет.

Обязательно используйте хранилище кода. Тут выбор за вами: GitHub, Bitbucket или GitLab (российских аналогов пока нет). Все они имеют приватные репозитории на бесплатных тарифах и поддерживают работу с Git.

Создайте репозиторий (или несколько) для проекта в одном из хранилищ. В нем должно быть как минимум две ветки. Названия могут быть любыми, но чаще их называют как-то так:

  • dev – ветка для dev-сервера (создается от ветки master).

  • master – ветка для prod-сервера.

Клонируйте репозиторий проекта на dev-сервер и переключитесь на ветку dev. Проделайте то же самое для prod-сервера, но используйте ветку master.

Принцип такой: начали делать новую «фичу» или исправлять «баг» — создаете новую ветку от ветки dev. Закончили работу в новой ветке — вливаете ее в ветку dev. Получаете и тестируете все на dev-сервере. Если все хорошо, то вливаете ветку dev в ветку master и выкатываете изменения на prod-сервер.

Разверните сервера на ОС Linux. Чаще всего используют Centos 7 или Ubuntu 20.04 LTS. Могут быть и другие Linux, выбор за вами. Важно использовать версии ОС с длительным сроком поддержки (Long-Term Support — LTS).

ОС от Microsoft (Windows Server) используется только для специфичных проектов, где без нее не обойтись. Не забывайте, что за лицензию регулярно придется доплачивать облачному провайдеру.

Я рекомендую «заскриптовать» развертывание сервера. Создайте репозиторий с bash-скриптами, которые устанавливают необходимые сервисы, «подсовывают» в них нужные конфиги и поднимают (запускают) их. Да, на это нужно потратить время, но вы получите ряд преимуществ:

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

  • сервера не должны «падать», но они так иногда делают. Скрипты помогут вам быстро «поднять» новый сервер, причем точно такой же, как старый.

Админы делятся на три типа: которые не делают бэкапы, которые уже делают бэкапы, которые проверяют созданные бэкапы. Давайте угадаем, кто поступает правильно.

Обязательно делайте бэкапы данных — дампы баз данных, файлов пользователей и т. д. Их можно хранить у тех же облачных провайдеров, это не очень дорого. Конечно, все зависит от объема, но хранение пары сотен ГБ обойдется дешевле стоимости сервера, приведенного выше. Если ваша система позволяет работать с файлами, хранящимися в удаленной корзине типа S3, то сразу храните файлы в таких хранилищах у облачных провайдеров.

Не забывайте про файрвол. Эта ваша первая линия защиты, ведь ваш сервер доступен из сети Интернет.

Если ваше приложение работает через браузер, а все остальное пока находится на том же сервере, то достаточно открыть SSH, HTTP и HTTPS и закрыть остальные порты. Современные IDE и клиенты СУБД прекрасно умеют работать «over SSH». Поищите, как это настроить и вы прикроете множество уязвимостей для вашего приложения.

Еще я бы порекомендовал поменять SSH порт с 22 на какой-нибудь другой, например, 2200 и использовать SSH-ключи вместо логина и пароля.

Если облачные провайдеры предоставляют файрвол, который стоит на границе облачной сети и Интернет — настраивайте его. Если нет, то разворачивайте свой сервер (на ОС Centos 7), устанавливайте iptables и заскриптуйте правила при помощи bash. В следующий раз, когда вам понадобиться что-то открыть или закрыть, то вы допишете правило в скрипт и выполните его. Это лучше, чем вычитывать, что же у вас открыто и закрыто действующими правилами. Принцип написания скрипта прост:

  1. Сбрасываете все действующие правила.

  2. Объявляете политику по умолчанию (я предпочитаю «Все запрещено»).

  3. Разрешаете то, что необходимо. Например, SSH, HTTP и HTTPS.

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

  1. Скрипт, который сбрасывает все правила и ставит политикой по умолчанию «Все разрешено». Иногда надо быстро проверить, не в файрволе ли проблема. 

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

  3. Скрипт сохранения правил, использующий утилиту iptables-save. Нужен потому что iptables хранит изменения правил только до перезагрузки ОС. Чтобы сохранить нужные правки, используем этот скрипт. 

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

  1. Flowlu.

  2. Аспро.Agile.

  3. Kaiten.

  4. Битрикс24.

  5. YouGile.

Количество пользователей растет

Значит нагрузка на prod-сервер тоже увеличилась. Вы оптимизируете код и запросы в СУБД. Это временно помогает, но не решает проблему, так как пользователи все приходят. В этом же и была цель приложения?

Пришло время изменить архитектуру prod-сервера. Дело это не быстрое, поэтому нужно выиграть время. В этом поможет вертикальное масштабирование. Пока просто добавьте ресурсы на prod-сервер: CPU, RAM, увеличьте объем диска.

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

Архитектура с «Бастионным узлом»

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

Есть другой вариант: развернуть свой сервер с минимальными характеристиками. 1 ядро, 1 ГБ ОЗУ и минимальный, пусть даже медленный, диск. Ставите на него Centos 7 и iptables. Создаете репозиторий и скриптуете правила iptables с проброской по порту на нужный сервер.

В первую очередь с единого prod-сервера выносят СУБД. Возможно, что вам потребуется вынести что-то еще. Смотрите, что создает нагрузку и выносите этот сервис на отдельный сервер.

Если вы ранее скриптовали установку prod-сервера, то теперь вы создаете два репозитория. В один выносите скрипты по развертыванию СУБД, а в другой все остальное. Разворачиваете два сервера: СУБД и приложения. На файрволе делаете проброску портов HTTP и HTTPS на сервер приложений.

Так, стоп. Мы же не пробросили SSH? Конечно, это можно было сделать. Но я предлагаю подумать о будущем и сделать лучше.

Нужно развернуть еще один сервер, который называется терминальным. Пока хватит 2 ядра, 4 ГБ ОЗУ и быстрого диска на 20 ГБ. Терминальный сервер будет работать под управлением ОС Ubuntu 20.04 LTS с графическим интерфейсом, службой VNC и/или RDP. Также на него следует поставить IDE и клиент СУБД. Позже на нем можно развернуть средства мониторинга всех серверов. Например, grafana+prometheus или zabbix. Осталось пробросить SSH-порт на файрволе к терминальному серверу.

На терминальном сервере у нас развернут VNC и/или RDP, а проброшен только доступ по SSH. Так зачем тогда вообще нужен графический интерфейс?

Ответ прост: нужно подключаться VNC over SSH и/или RDP over SSH. До файрвола у нас будет шифрованный канал (SSH), а на терминальный сервер мы подключимся уже по графическому интерфейсу. В итоге терминальный сервер будет вашим рабочим местом в приватной облачной сети. На него можно установить любое нужное ПО и безопасно подключаться к облачным серверам.

Какие преимущества мы получим от этих действий:

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

  2. Единая точка входа «Бастионный узел»:

    1. Очень легко контролировать доступ.

    2. Скрытая архитектура вашего приложения.

    3. Легко масштабироваться в дальнейшем.

  3. Работа на серверах только с доверенного устройства — терминального сервера.

  4. Шифрованный канал связи, но в отличие от VPN дополнительные настройки не требуются.

Используйте Docker, а лучше docker-compose

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

И тут мы сталкиваемся с еще двумя проблемами:

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

  2. У разработчика на ПК новая «фича» работала нормально, залили на dev-сервер — ничего не работает. Чудеса, да и только. У этой проблемы даже есть имя: различные среды для разработки, тестирования и эксплуатации.

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

Да, конечно, скрипты развертывания локальной, dev и prod версии системы будут отличаться, но в них много общего. Главное: мы получим единую среду разработки, тестирования и эксплуатации. Поверьте, это очень важно.

Если вы подготовите развертывание приложения через докер к моменту перехода на архитектуру с «Бастионным узлом», то убьете двух зайцев:

Заяц 1: Вам не потребуется еще раз развертывать сервера и переносить данные.

Заяц 2: В вашем приложении еще нет тысяч пользователей и процесс миграции на современные технологии будет менее болезненным. Чем дольше вы будете оттягивать переезд на Docker, тем будет сложнее миграция. 

А что дальше?

После всего вышеописанного можно посоветовать:

  1. Автоматизировать развертывание кода через pipeline, используя концепцию CI/CD.

  2. Мониторить нагрузку и переходить на горизонтальное масштабирование ресурсов с использованием балансировщиков нагрузки при необходимости. Я бы посоветовал посмотреть в сторону Kubernetes. Тем более некоторые облачные провайдеры предлагают его в качестве PaaS. Но не забывайте, что ваше приложение должно уметь работать с балансировщиком нагрузки.

В заключение повторюсь: приложение должно эволюционировать,  постепенно адаптироваться под реалии.

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

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

Теги:
Хабы:
+5
Комментарии6

Публикации

Истории

Работа

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн