Дробим монолит: Рефакторинг архитектуры Web-приложений

5dc532fe95b14bc6acea091d40794534.jpg

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

Вместе с Виктором gritzko Грищенко, создателем swarm.js (https://twitter.com/gritzko), рассмотрим современные подходы к построению архитектуры JS приложений как на сервере, так и на клиенте.

— Когда мы говорим о монолитных Web-приложениях, обычно имеется в виду архитектура, ставшая уже классической. Так называемый слоистый монолит хорошо прижился во многих корпоративных решениях. Расскажите, с какими недостатками данной архитектуры вам приходилось бороться в реальных проектах?

f5141ae5936a4e51a0c7dd6ffe44ec33.jpg
 — С такой классической архитектурой я впервые столкнулся ещё в 2000 году в Банке России. Причём возникла она сама собой, в процессе аврального внедрения. Получился вполне обычный enterprise Java кошмарик, когда систему можно было запускать только целиком и только на сервере, с полной БД. Что-то сделать с получившимся монолитом было уже трудно, всё зависело от всего. Позже я видел такие же факапы в Яндексе. Это неизбежный этап, если приложение перерастает свою архитектуру.

— Как понять, что монолитный проект пора разделять на сервисы? Существуют характерные признаки?

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

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

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

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

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

В общем-то, доклад не про микросервисы. Я прикладываю идеи «иммутабельной инфраструктуры» непосредственно к фронтенду, к тому, что работает в браузере.

— Хорошо, давайте обсудим код на клиенте. Какие проблемы сейчас актуальны?

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

Вытаскивание данных на клиента идёт полным ходом — сначала вытащили код, появились SPA, теперь постепенно вытаскиваем данные, хотим offline-first, быстрое время отклика и прочие плюшки.

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

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

— Моя затея в том, чтобы строго разделить всё происходящее на фронтенде на (А) данные и (Б) всё остальное (компоненты, код). Причём, всё, что не данные — то функции. А функции — тоже данные, если подумать. Когда мы кладём код в систему контроля версий, он становится данными. То есть, у нас есть версионированные данные и версионированные функции, которые мы доставляем на клиент одинаково, одинаково кешируем и обновляем.

— А если чуть подробнее?

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

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

В конечном счёте фундаментальная проблема здесь одна — и код, и данные должны работать на множестве устройств одновременно. Мы строим распределенные системы просто потому, что процессоры уже везде. Телефон — компьютер, книга — компьютер, телевизор — компьютер. Клиент-серверное мышление уйдёт в прошлое так же, как мейнфреймы ушли. А что придёт на смену — интересный вопрос.

— Звучит интересно, но как это совместимо с существующими библиотеками и фреймворками? Даже для частичной работы приложения потребуются большие основные зависимости (AngularJS, jQuery, …).

— Ну, preact уложились в 3KB как-то.
Angular применять в таком контексте действительно незачем.

— Данная концепция уже сформировалась в отдельный проект? Где можно узнать подробности?

— Укладывается. Сейчас это скорее эксперименты. К декабрю расскажу, что получилось.

Кроме доклада Виктора на конференции HolyJS (11 декабря, Москва, Radisson «Славянская»), рекомендуем обратить внимание на следующие доклады:

  • ECMAScript: latest and upcoming features
  • Building Interactive npm Command Line Modules
  • Лебедь рак и щука: как технологии тянут фронтенд на дно
  • 3L3M3NT5
  • Как подойти к современным веб-приложениям
  • Debugging Node.js Performance Issues in Production
  • WebVR is the next frontier
  • A Little Closer to Frontend Bliss with Elm
  • Performance Profiling for V8
  • Свои инструменты без шуму и пыли
  • Rich text editing with Draft.js
  • Offline is the new Black
  • Sharing files and data with friends using a P2P shared folder powered by javascript

Комментарии (0)

© Habrahabr.ru