Дробимо моноліт: Рефакторинг архітектури 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 «Слов'янська»), радимо звернути увагу на наступні доповіді:

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.