Как устроен lesorub.pro
Чемпионат идёт к завершению, поэтому расскажу как сайт устроен. Вообще это всё чистый couchapp, давно забытая в веках технология.
Couchapp – это когда есть CouchDB, и она для всего, а больше кроме CouchDB ничего и нет. Я в чистом виде так ещё не делал, всегда был node.js ещё как минимум. В этот раз node.js нет, но в архитектуру couchapp добавлено два слоя – JS rewrite на сервере и PouchDB на клиенте.
JS rewrite, только появившийся в CouchDB 2.0 моими и @kxepal трудами, позволяет делать сложный раутинг прямо внутри БД. То-есть кастомные API, access control и тп.
Вторая фича, PouchDB на клиентах бэкэнда, – позволяет делать тяжёлые веб-приложения бэкэнда с отзывчивостью десктопного уровня, ну и работать при плохих соединениях. “Тяжёлые” – это значит ворочать бинарными данными в мегабайты, картинки там обрабатывать, пдф-ки, сложные виджеты инлайнить с данными в реальном времени.
Архитектура одного узла выглядит так (может быть из одной, двух или трёх физ. машин):

То-есть, node.js-а нет. Совсем нет. Есть только CouchDB и nginx, которые gzip-ит ответы и приписывает Cache-control к статическим ресурсам. Статические ресурсы тоже отдаются из CouchDB есчо. Довольно кстати быстро, потому что они в CouchDB хранятся уже зазипованные.
Ещё нет файлов на файловой системе даже при разработке. Всё вообще в браузере и БД.
Все JS-функции на сервере – stateless и без сайд-эффектов, они компилируются из кода бэкэнд-приложений прямо в браузерной IDE и тоже хранятся в БД. Большинство функций рантаймят в отдельных экземплярах SpiderMonkey (JS-машина уровня Firefox 4.0, с 64Мб памяти, ога) и исполняются под контролем Erlang-процессов.
64 Мб на JS-процесс, кста, было серьёзным challenge, когда клиентский апп редактора контента нужно было перекомпилить в серверный, синхронный, и до памяти не жоркий.
На 2x i5 <2GHz + 2Gb RAM, без всякой специальной оптимизации JS-кода, оно показывает вот такую производительность (выброс связан с особенностями хостинга):
Клик – результаты на лоадимпакте целиком.
Тут от 10 до 20 юзеров публичной части одновременно, загружающих 126 ресурсов внутри 6 страниц (по кругу, через 2-4 секунды). Пиковая скорость 100rps, bandwidth ~40Mbit/s. Всего 23К запросов, 1.1Гб данных, все 200 ОК.
Результат средненький – с нодом это было бы втрое лучше при меньшем на ~10-15ms latency. Но втрое лучше не нужно, хотя понятно, где можно существенно выиграть.
Например, сейчас routing (это JS rewrite) выполняется паттерн-матчингом примерно такого вот синтаксиса, в Эрланговском стиле:
Он всем прекрасен, этот синтаксис, но страшно медленный – то-же самое, переписанное кровавым месивом if-then, работает впятеро быстрее. У меня пока руки не дошли написать транслятор, хотя это как раз даст те самые минус 10ms latency.
В общем, технология не выглядит прорывом, но у неё есть несколько специфических особенностей, которые мне нужно было попробовать – и я остался целиком результатом удовлетворён.
- Однажды запущенный нод полностью управляется из браузера.
- Ноды прекрасно объединяются в федерации, как в плане агрегации/расшаривания данных, так и в плане деплоя кода клиентских приложений и серверных лямбд. Юзер-эккаунты с разных нодов тоже могут федерироваться.
- Сервер – Эрланг и JS-функции без сайд-эффектов, то-есть неубиваемый вообще.
- Любой нод сам по себе может быть сплитнут горизонтально (отдельные машины/кластеры разной мощности под dev, backend и www).
- Весь код всего обновляется на лету.
- Развернуть новый нод – минуты. Надо ещё сделать чтобы настройка тоже занимала минуты.
Но небыстрое конечно, и дедушкиным зипуном-с отдаёт с LAMP-овой теплотой, хехе )
UPD. Вот, на всякий случай, тоже тёплое ламповое похожей архитектуры, но с node.js-ом. 1000rps, 300Мбит/с на вдвое более мощной железяке.