LINUX.ORG.RU

[webdev] Покритикуйте архитектуру


0

1

В последнее время мне всё больше нравится такая схема разработки веб-приложений:

  • Берётся веб-сервер который умеет хорошо раздавать статику и поддерживает FastCGI. Например, nginx.
  • Все html, css и js раздаются им исключительно статически.
  • Динамической шаблонизации нет, если какой-то html нужно собирать из кусков (шаблонов, комбинаторов, etc.), то это делается статически, а не во время отдачи клиенту.
  • Динамических путей (routes) тоже нет - только поддерживаемые веб-сервером.
  • Если страница всё же должна содержать динамический контент, то в статически отдаваемом html делается пустой div и пишется js-приложение которое асинхронно загружает в него нужное с fastCGI ресурса аяксом.
  • Протоколом между js-приложением и fastCGI ресурсом может служить bison (бинарный JSON).
  • Сами fastCGI-приложения более менее независимы друг от друга (но могут быть DB зависимы) и могут писаться на любом удобном языке (language agnostic).
  • Если сильно нужно, то для динамических путей можно сделать redirect на fastCGI ресурс средствами веб-сервера. Или сразу использовать URI таких ресурсов.

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

Какие ещё могут быть проблемы с такой схемой? Кто-нибудь вообще так делает?

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

Где собирать html - можно сделать, чтобы было и так и так.

stevejobs ★★★★☆ ()

1. nginx, статика, реврайтер, TLS.

2. HTML на серверной стороне НЕ генерируется.

3. Данные лежат в MongoDB/CouchDB. Доступ по REST API. nginx обеспечивает фильтрацию, и красивые URLы.

4. Все остальное обеспечивает клиент. В широком смысле этого слова. Не обязательно браузер.

5. Если у какой-то часть приложения свой event-loop, то оно все-равно пишет данные в базу, откуда их по REST API берет клиент.

6. ...

7. PROFIT!!

Macil ★★★★★ ()

И в чем глубокий смысл этой схемы?

FYI тот же nginx прекрасно кеширует динамику (для вас читать как «перегоняет все в статику и отдает напрямую»). К слову, тот же json элементарно жмется на лету gzip'ом - вообще ума не приложу кому и зачем нужен его бинарный вариант.

BigAlex ★★★ ()

1) Лучше кешировать нгниксом в статику, он прекрасно с этим справляется.
2) Для динамического контента юзать ssi/esi, man блочное кеширование.

Ultimate-вариант: собирать нгниксом динамику в статику без инклюдов. Собирать варнишем статику+инклюды в готовую страницу.
http://rghost.net/34489651.view

iSage ★★★★ ()
Ответ на: комментарий от Macil

2. HTML на серверной стороне НЕ генерируется.

Т.е. не шаблонизируются (php, templates и т.п.), но какая-то статическая разметка (если клиент - браузер) всё равно быть должна.

3. Данные лежат в MongoDB/CouchDB. Доступ по REST API. nginx обеспечивает фильтрацию, и красивые URLы.

Хм, надо будет подумать можно ли сделать для nginx модуль для read/write с MongoDB (c TLS для write, наверное). Либо на mongolab.com держать базу, там есть read/write REST API.

quasimoto ★★★★ ()
Ответ на: комментарий от BigAlex

nginx прекрасно кеширует динамику

Он мне каждую секунду будет её кешировать? :) Суть в том, что начиная с php динамически генерирует зачем-то всю страницу, тогда как зачастую страница наперёд известна за исключением каких-то динамических кусков. Эти куски можно либо вставить с помощью чего-то вроде SSI, либо заставлять клиента самому их вставлять - ajax-ом обращаться к ресурсам приделанным к базе.

Пока я вижу тут только одну проблему - индексирование страниц поисковиками. Может, в будущем они научатся выполнять ajax запросы, тогда эта проблема отпадёт.

К слову, тот же json элементарно жмется на лету gzip'ом - вообще ума не приложу кому и зачем нужен его бинарный вариант.

Компрессия/декомпрессия это одно, а сериализация/десериализация в бинарное представление - другое.

quasimoto ★★★★ ()

Ещё такой вопрос - как nginx работает с fastcgi? Он их обрабатывает в своём event loop или создаёт треды? Если в event loop, то тогда получается вообще хорошо.

quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

но какая-то статическая разметка (если клиент - браузер) всё равно быть должна.

Должна. Называется index.html :) С пустым BODY и нужным SCRIPT.

Более того, тебе абсолютно ничего не мешает хранить в базе и самые обычные куски HTML/XML и даже JS. Клиентское приложение не заметит разницы. Вообще.

можно ли сделать для nginx модуль для read/write с MongoDB

Это будет КРАЙНЕ сложно сделать, ввиду архитектуры nginx. Но самое главное ЗАЧЕМ? У MongoDB или CouchDB есть прекраснейший REST API. Т.е. приложение через AJAX или какие-то другие технологии может запрашивать данные напрямую, и без каких-то промежуточных слоев на клиентском уровне. Например, http://www.mongodb.org/display/DOCS/Http Interface а потенциально негативные эффекты такого подхода нивелируются использованием reverse-proxy, в т.ч. и с аутентификацией по клиентским сертификатам, фильтрацией, и способами создания красивых URL.

У nginx есть штатный модуль для доступа к memcached. По идее, через него можно работать и с MemcacheDB, хотя это всего лишь БД ключ-значение.

Macil ★★★★★ ()

Кто-нибудь вообще так делает?

keywords: csi, js.

quasimoto ★★★★ ()
Ответ на: комментарий от Macil

Это будет КРАЙНЕ сложно сделать, ввиду архитектуры nginx

Я просто уже видел такой модуль (на си написан) на github-е, но он только читать умеет.

У MongoDB или CouchDB есть прекраснейший REST API.

У монги про simple REST interface написано, что The mongod process includes a simple read-only REST interface for convenience. For full REST capabilities we recommend using an external tool such as Sleepy.Mongoose. Тогда как писать в базу? Через fastCGI-ресурсы?

quasimoto ★★★★ ()

Кто-нибудь вообще так делает?

На моём фреймворке всё описанное (вроде бы) делается штатными средствами «за 5 минут».

Но смысла что-то не вижу особого. В 99% случаев с нагрузкой прекрасно справляется и динамика + чистая генерируемая статика. Ну а 1% случаев, когда используется статика, оживляемая AJAX'ом — это слишком банально, чтобы делать какие-то концептуальные выводы :)

KRoN73 ★★★★★ ()
Ответ на: комментарий от Macil

Должна. Называется index.html :) С пустым BODY и нужным SCRIPT.

It's bad for your health^W SEO :)

quasimoto ★★★★ ()
Ответ на: комментарий от KRoN73

В 99% случаев с нагрузкой прекрасно справляется и динамика + чистая генерируемая статика. Ну а 1% случаев, когда используется статика, оживляемая AJAX'ом — это слишком банально, чтобы делать какие-то концептуальные выводы :)

Ну, весь вопрос в том какой способ выбирается за основной - если писать 99% динамики и 1% статики с AJAX-ом, то всё так, но если делать всё наоборот (например, нам не нужно искать по динамическому контенту), то CSI как-то проще выглядит, да и неохота заморачиваться с шаблонизацией (исключительно на мой взгляд).

quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

It's bad for your health^W SEO :)

Пардон, а какой же SEO в веб-приложении? Хотя SSI или вообще набор заранее сгенерированных спасет.

Тогда как писать в базу? Через fastCGI-ресурсы?

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

И забудь ты про это идейное убожество (Fast)CGI. Не нужен FastCGI в данном случае. Вообще, не нужен. Архитектура простая клиент <-> морда <-> бэкенд. Везде самый обычный HTTP. Морда частично выполняет служебные функции: отдача статики, TLS, и прикрывает нежное тельце бэкенда от сурового Интернета.

Понятно дело, что бэкенд - гетерогенная сущность: разные демоны, разные сервера, разные реализации. Удобно данный, конкретный бэкенд писать на лиспе - пиши на лиспе, кривую реализацию HTTP прикроет морда, она же сделает так, чтобы бэкенд не окочурился под нагрузкой, десятком же способов, начиная от банального ratelimit, заканчивая memcached и балансировкой. Удобно данный бэк-енд писать на Node.js - пиши на Node.js и т.д. и т.п.

Нужна тебе аутентификация? Подними на морде TLS c клиентскими сертификатами (единственный расово верный способ в случае корпоративных веб-приложений, хотя nginx обеспечивает и другие). Морда возьмет на себя всю TLS-специфичную фигню, и вышлет бэкенду нужные X-заголовочки для проведения авторизации.

ЗЫ: А вообще - банальнейший же юникс-вей...

Macil ★★★★★ ()
Ответ на: комментарий от Macil

Пардон, а какой же SEO в веб-приложении?

Если в some.html пустой body, то это исключает всякую возможность SEO. Хотя, говорят, что гугл уже научился делать AJAX.

Во-вторых, писать в БД по идее должно само веб приложение по POST запросу со всесторонней проверкой и проч. Значит - это задача конкретного бэкенда.

Сейчас у меня в js вещи вида «<some event> ... $.post(„dynamic/some_post.cgi“, ...)» и «<some event> ... $.get(„dynamic/some_get.cgi“, ...)». Первое делает разные проверки и пишет в БД, а второе формирует ответ на основе чтения из БД. Вместо бакэнда - fastcgi.

И забудь ты про это идейное убожество (Fast)CGI. Не нужен FastCGI в данном случае. Вообще, не нужен. Архитектура простая клиент <-> морда <-> бэкенд. Везде самый обычный HTTP. Морда частично выполняет служебные функции: отдача статики, TLS, и прикрывает нежное тельце бэкенда от сурового Интернета.

Да это-то всё понятно, я так и делал всё время. Но в чём конкретно идейное убожество (Fast)CGI - почему нельзя обращаться из js с помощью get/post к ресурсам сделанным как fastcgi приложения?

quasimoto ★★★★ ()
Ответ на: комментарий от Macil

Во-первых, REST вроде как, у CouchDB несколько лучше.

CouchDB как-то не хочется :)

quasimoto ★★★★ ()
Ответ на: комментарий от trashymichael

Покритикуйте архитектуру

убого

Очень конструктивно, да.

quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

не обращай на него внимания - он всегда такой.

anonymous ()

Интересно сравнить скорость разбора json и bson в браузере. Json будет парситься браузером, а bson - js кодом.

Ну и потом до кучи сравнить с thrift. Помнится кто-то из известный вебдванольных сервисов использовал его для эффективности

maxcom ★★★★★ ()

Вообще есть малоизвестная фича, позволяющая на стороне клиента инклудить html в html безо всяких js.

1.html

<html>
<body>
<div style="border:1px solid blue">
<h1> this is file 1</h1>
<object data=2.html></object>
</div>
</body>
</html>

2.html

<html>
<body>
<div style="border:1px solid red">
<h1>this is file 2</h1>
</div>
</body>
</html>

скриншот

Что будет с индексацией поисковиками - не знаю. Про широту поддержки браузерами тоже не знаю, вроде в ie6 не работало.

legolegs ★★★★★ ()
Ответ на: комментарий от legolegs

Вообще есть малоизвестная фича, позволяющая на стороне клиента инклудить html в html безо всяких js.

Подойдёт, если всё что нужно это делать $("...").load по событию $(document).ready, но если логика более сложная и нужны $.get, $.post по другим событиям с выполнением каких-то действий при удачном ответе ресурса, то без js уже никак.

quasimoto ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.