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



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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




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

    • +18
    • 12,8k
    • 4
    JUG.ru Group
    919,00
    Конференции для взрослых. Java, .NET, JS и др. 18+
    Поделиться публикацией

    Комментарии 4

      0
      Читая заголовок мне и в голову не пришло что это фактически тизер конференции HolyJS…
        +4
        Описанная идея очень интересная, ещё хотелось бы увидеть нормальную реализацию — тогда может взлететь.
        А за наводку на preact огромное спасибо.
          +1
          1С — там всю жизнь так было: код качается с сервера из базы.
          +4
          Очень похоже на то как работает requirejs из коробки.
          Так раньше часто проекты работали, потом начали все сжимать в один файл, теперь снова начали делить :)

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

          Самое читаемое