Разработка web приложений


НОУ ИНТУИТ | Лекция | Разработка Web-приложений

Аннотация: Одна из главных сфер применения языка Python - web-приложения - представляется в этой лекции на конкретных примерах. Кроме того, делается акцент на типичных слабых местах безопасности web-приложений.

Под web-приложением будет пониматься программа, основной интерфейс пользователя которой работает в стандартном WWW-браузере под управлением HTML и XML-документов. Для улучшения качества интерфейса пользователя часто применяют JavaScript, однако это несколько снижает универсальность интерфейса. Следует заметить, что интерфейс можно построить на Java- или Flash-апплетах, однако, такие приложения сложно назвать web-приложениями, так как Java или Flash могут использовать собственные протоколы для общения с сервером, а не стандартный для WWW протокол HTTP.

При создании web-приложений стараются отделить Форму (внешний вид, стиль), Содержание и Логику обработки данных. Современные технологии построения web-сайтов дают возможность подойти достаточно близко к этому идеалу. Тем не менее, даже без применения многоуровневых приложений можно придерживаться стиля, позволяющего изменять любой из этих аспектов, не затрагивая (или почти не затрагивая) двух других. Рассуждения на эту тему будут продолжены в разделе, посвященном средам разработки.

CGI-сценарии

Классический путь создания приложений для WWW - написание CGI-сценариев (иногда говорят - скриптов). CGI (Common Gateway Interface, общий шлюзовой интерфейс) - это стандарт, регламентирующий взаимодействие сервера с внешними приложениями. В случае с WWW, web-сервер может направить запрос на генерацию страницы по определенному сценарию. Этот сценарий, получив на вход данные от web-сервера (тот, в свою очередь, мог получить их от пользователя), генерирует готовый объект (изображение, аудиоданные, таблицу стилей и т.п.).

При вызове сценария Web-сервер передает ему информацию через стандартный ввод, переменные окружения и, для ISINDEX, через аргументы командной строки (они доступны через sys.argv ).

Два основных метода передачи данных из заполненной в браузере формы Web-серверу (и CGI-сценарию) - GET и POST. В зависимости от метода данные передаются по-разному. В первом случае они кодируются и помещаются прямо в URL, например: http://example.com/cgi-bin/a.cgi?a=1&b=3. Сценарий получает их в переменной окружения с именем QUERY_STRING. В случае метода POST они передаются на стандартный ввод.

Для корректной работы сценарии помещаются в предназначенный для этого каталог на web-сервере (обычно он называется cgi-bin ) или, если это разрешено конфигурацией сервера, в любом месте среди документов HTML. Сценарий должен иметь признак исполняемости. В системе Unix его можно установить с помощью команды chmod a+x.

Следующий простейший сценарий выводит значения из словаря os.environ и позволяет увидеть, что же было ему передано:

#!/usr/bin/python import os print """Content-Type: text/plain %s""" % os.environ

С помощью него можно увидеть установленные Web-сервером переменные окружения. Выдаваемый CGI-сценарием web-серверу файл содержит заголовочную часть, в которой указаны поля с мета-информацией (тип содержимого, время последнего обновления документа, кодировка и т.п.).

Основные переменные окружения, достаточные для создания сценариев:

Строка запроса.

IP-адрес клиента.

Имя клиента (если он был идентифицирован).

Имя сценария.

Имя файла со сценарием.

Имя сервера.

Название браузера клиента.

Строка запроса (URI).

Желательный язык документа.

Вот что может содержать словарь os.environ в CGI-сценарии:

{ 'DOCUMENT_ROOT': '/var/www/html', 'SERVER_ADDR': '127.0.0.1', 'SERVER_PORT': '80', 'GATEWAY_INTERFACE': 'CGI/1.1', 'HTTP_ACCEPT_LANGUAGE': 'en-us, en;q=0.50', 'REMOTE_ADDR': '127.0.0.1', 'SERVER_NAME': 'rnd.onego.ru', 'HTTP_CONNECTION': 'close', 'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.0.1) Gecko/20021003', 'HTTP_ACCEPT_CHARSET': 'ISO-8859-1, utf-8;q=0.66, *;q=0.66', 'HTTP_ACCEPT': 'text/xml,application/xml,application/xhtml+xml, text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg, image/gif;q=0.2,text/css,*/*;q=0.1', 'REQUEST_URI': '/cgi-bin/test.py?a=1', 'PATH': '/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin', 'QUERY_STRING': 'a=1&b=2', 'SCRIPT_FILENAME': '/var/www/cgi-bin/test.py', 'HTTP_KEEP_ALIVE': '300', 'HTTP_HOST': 'localhost', 'REQUEST_METHOD': 'GET', 'SERVER_SIGNATURE': 'Apache/1.3.23 Server at rnd.onego.ru Port 80', 'SCRIPT_NAME': '/cgi-bin/test.py', 'SERVER_ADMIN': '[email protected]', 'SERVER_SOFTWARE': 'Apache/1.3.23 (Unix) (Red-Hat/Linux) mod_python/2.7.8 Python/1.5.2 PHP/4.1.2', 'SERVER_PROTOCOL': 'HTTP/1.0', 'REMOTE_PORT': '39251' }

Следующий CGI-сценарий выдает черный квадрат (в нем используется модуль Image для обработки изображений):

#!/usr/bin/python import sys print """Content-Type: image/jpeg """ import Image i = Image.new("RGB", (10,10)) i.im.draw_rectangle((0,0,10,10), 1) i.save(sys.stdout, "jpeg")

www.intuit.ru

НОУ ИНТУИТ | Лекция | Основы функционирования веб-приложений

Аннотация: Эта лекция содержит общую информацию о функционировании веб-приложений. Здесь рассматриваются основные протоколы и механизмы, которые задействованы в процессе работы веб-приложений. Рассмотрение вопроса идет с точки зрения общих концепций и не зависит от конкретных решений или платформ.

Как работают веб-приложения

Цель лекции: сформировать концептуальное представление о функционировании веб-приложений.

Веб-приложения – это специальный вид приложений, которые работают в глобальной сети Интернет по протоколу HTTP (см. "Введение в платформу .NET Framework и ASP.NET" ). Как правило, веб-приложения не требуют установки дополнительного программного обеспечения на стороне клиента, а вся логика, в основном, выполняется на стороне сервера. Для отображения пользовательского интерфейса используется браузер – программа, способная распозновать язык разметки HTML (и сопутствующие технологии – таблицы стилей CSS, клиентский скриптовой язык программирования JavaScript и т.д.). Браузер обычно принято называть "тонким клиентом", т.е. клиентом, который содержит минимальное количество бизнес-логики.

Давайте разберемся в том, как функционирует любое веб-приложение. Необходимые компоненты для работы пользователя с веб-приложением – браузер (тонкий клиент), веб-сервер (серверная часть), протокол взаимодействия клиента и сервера (HTTP) и язык разметки для создания документов (HTML). Основу функционирования веб-сервера и протокола HTTP мы подробнее рассмотрим в следующих лекциях, а пока остановимся на концептуальном представлении. Для того, чтобы веб-приложение стало доступно, его необходимо разместить в рамках веб-сервера (специальная программа, которая обрабатывает запросы из сети). После этого приложение получит свой уникальный адрес в рамках протокола HTTP (например, http://www.myapplication.com/page1.html). Используя этот адрес пользователь может обратиться к приложению. Для этого он должен запустить браузер (клиентское приложение) и ввести в адресной строке адрес приложения. В этот момент браузер сгенерирует запрос к серверу и отправит его, используя протокол HTTP. В момент, когда сервер примет этот запрос, он сможет распознать, что именно требуется от него на основе полученного запроса. Используя эти данные он сгенерирует ответ и отправит его обратно клиенту также используя протокол HTTP. Обычно ответ содержит гипертекстовую разметку HTML, содержащую структуру документа, который передается пользователю. После того, как браузер получит ответ в виде HTML-документа, он немедленно отобразит его пользователю. Таким образом, было совершено взаимодействие клиента и сервера. Зачастую документ HTML содержит ссылки на изображение, другие медиа-файлы, таблицы стилей или клиентские сценарии. В этом случае браузер генерирует еще несколько аналогичных запросов к веб-серверу. Однако, в этом случае веб-сервер передает клиенту уже не HTML-документ, а соответствующие запрашиваемые ресурсы (изображения, таблицы стилей, клиентские сценарии и т.д.).

В самом простейшем случае на сервере может быть сохранен готовый документ HTML, который по запросу будет передаваться пользователю. Это – так называемый, статический документ. В этом случае он просто считывается с жесткого диска и передается клиенту. Однако, такой сценарий работы в глобальной сети становится все более редким. Другой подход – генерация кода HTML в процессе обработки запроса от клиента. Этот подход позволяет сделать веб-приложение более интерактивным, отзывчивым на действия клиента и создающее впечатления настоящего приложения, а не простой загрузки HTML-документов. Таким образом, мы, имея возможность генерировать HTML-код страницы, можем влиять на ту информацию, элементы управления и другие аспекты интерфейса, которые увидит пользователь. По сути, задача веб-приложения и заключается в том, чтобы генерировать нужный HTML-код, в зависимости от действий пользователя. Однако, возможности веб-приложений могут не ограничиваться только генерацией разметки HTML – они могут генерировать изображения, клиентские сценарии, таблицы стилей и другие ресурсы, которые могут быть загружены пользователем. Тем не менее, основным сценарием является все-таки генерация конечного документа HTML.

Как уже говорилось ранее, для взаимодействия клиента и сервера используется протокол HTTP (который более детально будет рассмотрен в последующих лекциях). Сейчас важно понять, что этот протокол работает по схеме "запрос-ответ". В момент, когда клиент хочет обратиться к серверу, он генерирует запрос, который отправляется серверу. Сервер обрабатывает этот запрос и подготавливает ресурсы, которые будут отправлены клиенту. После этого сервер генерирует ответ, в котором содержаться все необходимые данные и отправляет клиенту. Работа веб-приложений заключается в формировании необходимых данных как раз в момент подготовки ресурсов на сервере. Обычно в этот момент запускается некоторый программный код, который содержит определенную бизнес логику. Схему работы типичного веб-приложения схематически можно представить следующим образом (зеленым цветом обозначены действия, которые выполняются на клиентской стороне, а синие – на серверной).

Веб-приложения существенно отличаются от настольных приложений. Последние запускаются на компьютере клиента и выполняют свой код именно там. Поэтому настольные приложения зачастую обладают более богатым и отзывчивым пользовательским интерфейсом и позволяют реализовывать более богатые сценарии. По сравнению с настольными приложениями, веб-приложения обладают более ограниченными возможностями по формированию пользовательского интерфейса и клиентской функциональности. По этой причине за последнее время сложился стереотип о том, что серьезные приложения (например, бизнес-приложения) – это, как правило, настольные приложения. Однако, развитие веб-технологий доказало, что веб-приложения также могут реализовывать богатые сценарии и успешно конкурировать с настольными приложениями. Кроме того, за последние несколько лет очень активно развиваются технологии, позволяющие сделать веб-приложения еще более интерактивными. К ним относятся технология AJAX (будет рассмотрена в рамках курса), которая на основе клиентских сценариев JavaScript может сделать взаимодействие более интерактивным. Также существует ряд технологий, которые добавляют интерактивности приложению за счет внедрения в браузер специальных модулей (плагинов), которые могут отображать специальные типы файлов с более богатыми возможностями. К таким технологиям в первую очередь относятся технологии Silverlight и Flash.

Однако, несмотря на то, что существует ряд технологий, упрощающих создание динамичных веб-приложений, их разработка по прежднему остается довольно трудоемкой задачей. Разработка веб-приложений существенно отличается от разработки настольных систем. Этому есть две главные причины:

  • Веб-приложения исполняются на сервере. Весь программный код исполняется в рамках веб-сервера, а клиенту доставляется уже готовая разметка HTML, которая отображается внутри браузера.
  • Веб-приложения не хранят состояния. По-сути, сервер "забывает" про пользователя после того, как обработал его запрос.

Оба этих фактора существенно влияют на процесс разработки веб-приложений. Из-за этого при построении любого веб-приложения приходится решать типичные задачи – способы хранения информации о пользователе, организация сеансов работы пользователя, способы переходов от страницы к странице, механизмы оптимизации эффективности (например, кэширование) и др. При реализации каждого веб-приложения разработчику придется столкнуться с этими проблемами и решить их. Поскольку набор этих задач является достаточно стандартным и одинаково решается для большинства веб-приложений, то его реализация вынесена в отдельные технологии, которые называются технологиями для разработки веб-приложений. К таким технологиям относятся технология Microsoft ASP.NET, PHP, Ruby on Rails и др. В них, фактически, содержатся все компоненты, необходимые для реализации веб-приложений и учитывающие их специфику. Далее в рамках данного курса мы будем рассматривать разработку веб-приложений с позиции платформы Microsoft ASP.NET.

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

Краткие итоги

Веб-приложения работают на сервере и исполняются в рамках веб-сервера (специальной программы, обрабатывающей запросы). Взаимодействие клиента и сервера осуществляется про протоколу HTTP в рамках схемы "запрос-ответ". Вся логика веб-приложения размещается на сервере. Из-за этого появляются дополнительные проблемы при разработке веб-приложений. Настольные приложения имеют более богатый пользовательский интерфейс, но веб-приложения легче разворачивать и обновлять (особенно, если имеется большое количество рабочих мест). Пользовательский интерфейс веб-приложений может стать более интерактивным, если использовать дополнительные инструменты – клиентские сценарии JavaScript, а также приложения Silverlight, Flash и др.

www.intuit.ru

Семь принципов создания современных веб-приложений / Хабрахабр

Эта статья основана на моей презентации с конференции BrazilJS в августе 2014 года. Она базируется на идеях, о которых я писал в блоге недавно, в основном, в связи с UX и производительностью.

Я хочу представить 7 действенных принципов для веб-сайтов, которые хотят применить JavaScript для управления UI. Эти принципы являются результатом моей работы как веб-дизайнера, но также как давнего пользователя WWW.

JavaScript бесспорно стал незаменимым инструментом для разработчиков фронтенда. Сейчас сфера его применения расширяется на другие области, такие как серверы и микроконтроллеры. Этот язык программирования выбрали престижные университеты, чтобы обучать студентов основам информатики.

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

  • Должен ли JavaScript использоваться как замена функциям браузера: история, навигация, рендеринг?
  • Умирает ли бэкенд? Нужно ли вообще рендерить HTML?
  • Правда ли, что будущее за приложениями на одной странице (Single Page Applications, SPA)?
  • Должен ли JS генерировать страницы на веб-сайте и рендерить страницы в веб-приложениях?
  • Нужно ли использовать техники вроде PJAX или TurboLinks?
  • Каково точное отличие между веб-сайтом и веб-приложением? Должно ли остаться что-то одно?
Далее последуют мои попытки ответить на эти вопросы. Я попытался исследовать, как использовать JavaScript с точки зрения пользователя (UX). В частности, уделил особое внимание идее минимизации времени, которое требуется пользователю для получения интересующих его данных. Начиная с основ сетевых технологий и заканчивая предсказанием будущего поведения юзера.

1. Рендеринг страниц на сервере

tl;DR: Рендеринг на сервере осуществляется не ради SEO, а для производительности. Принимайте в расчёт дополнительные запросы для получения скриптов, стилей и последующие запросы к API. В будущем, принимайте в расчёт использование метода HTTP 2.0 Push. Прежде всего, я вынужден обратить внимание на общепринятую ошибку разделять «приложения с рендерингом на сервере» и «одностраничные приложения». Если мы хотим добиться наилучшего восприятия с точки зрения пользователя, то не должны ограничивать себя такими рамками и отказываться от одной альтернативы в пользу другой.

Причины вполне очевидны. Страницы передаются по интернету, у которого есть физические ограничения, что незабвенно проиллюстрировал Стюарт Чешир в знаменитом эссе «Это latency, дурачок»:

Расстояние между Стэнфордом и Бостоном 4320 км. Скорость света в вакууме 300 x 10^6 м/с. Скорость света в оптоволокне составляет примерно 66% скорости света в вакууме. Скорость света в оптоволокне 300 x 10^6 м/c * 0,66 = 200 x 10^6 м/c. Односторонняя задержка при передаче в Бостон 4320 км / 200 x 10^6 м/c = 21,6 мc. Задержка при передаче туда и обратно 43,2 мc. Пинг из Стэнфорда в Бостон в интернете современного образца около 85 мс (…) Итак, современное оборудование интернета передаёт сигнал со скоростью 0,5 от скорости света. Указанный результат 85 мс можно улучшить (и уже сейчас он чуть лучше), но важно понять, что существует физическое ограничение на задержку при передаче информации через интернет, как бы не увеличивалась полоса пропускания на компьютерах пользователей.

Это особенно важно в связи с ростом популярности JavaScript-приложений, которые обычно содержат только разметку <script> и <link> рядом с пустым полем <body>. Так называемые одностраничные приложения (Single Page Applications, SPA) — сервер возвращает одну страницу, а всё остальное вызывается кодом на клиентской стороне.

Представьте сценарий, когда пользователь напрямую заходит по адресу аpp.com/orders. К моменту, когда ваше приложение получает и обрабатывает этот запрос, у него уже есть важная информация о том, что нужно показывать на странице. Оно может, например, подгрузить заказ из базы данных и добавить его в ответ. А вот большинство SPA в такой ситуации возвращает пустую страницу и тег <script>. Потом придётся ещё раз обменяться запросами для получения содержимого скрипта, и ещё раз — для получения контента.

Анализ HTML, отправляемого сервером для каждой страницы SPA

Многие разработчики сознательно идут на такую жертву. Они стараются гарантировать, что дополнительные сетевые хопы для пользователя произойдут только один раз, отправляя правильные заголовки для кеширования в ответах со скриптами и CSS. Общепринятое мнение состоит в том, что это приемлемая сделка, потому что после загрузки всех файлов на компьютер большинство действий пользователя (как переходы в другие разделы) осуществляются без запросов дополнительных страниц или скриптов.

Однако, даже с учётом кеша, имеется определённый проигрыш в производительности, если учесть время на парсинг и выполнение скрипта. В статье «jQuery слишком большой для мобильника?» говорится, как один только jQuery может тормозить некоторые мобильные браузеры на сотни миллисекунд.

Что ещё хуже, обычно пользователь не получает никакого фидбека в то время, как загружаются скрипты. Результат — чистая страница на экране, которая потом внезапно превращается в полностью загруженную страницу.

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

TCP-соединение начинается с обмена пакетами для рукопожатия. Если вы используете SSL, что важно для безопасной передачи скриптов, происходит два дополнительных обмена пакетами (один, если клиент восстанавливает сессию). Только после этого сервер может начать отправку данных, но практика показывает, что он делает это медленно и порционно.

Механизм контроля заторов под названием Slow Start встроен в протокол TCP, чтобы отправлять данные, постепенно наращивая количество сегментов. Это имеет два серьёзных вывода для SPA:

1. Большие скрипты загружаются гораздо дольше, чем кажется. Как объясняется в книге "High Performance Browser Networking" Ильи Григорика, требуется «четыре обмена пакетами (…) и сотни миллисекунд задержки, чтобы выйти на 64 КБ обмена данными между клиентом и сервером». Например, в случае быстрого интернет-соединения между Лондоном и Нью-Йорком, требуется 225 мс, прежде чем TCP сможет выйти на максимальный размер пакета.

2. Поскольку это правило действует также для первоначальной загрузки страницы, то очень важно, какой контент грузится для рендеринга на странице в первую очередь. Как заключает Пол Ириш в своей презентации «Доставка товаров», критически важны первые 14 КБ. Это понятно, если посмотреть на график с указанием объёмов передачи между клиентом и сервером на первых этапах установки соединения.

Сколько КБ сервер может отправить на каждом этапе соединения, по сегментам

Веб-сайты, которым удаётся доставить контент (пусть даже базовую разметку без данных) в этом окне, кажутся исключительно отзывчивыми. На самом деле, многие авторы быстрых серверных приложений воспринимают JavaScript как нечто ненужное или что нужно использовать с большой осторожностью. Такое отношение ещё больше усиливается, если у приложения быстрые бэкенд и база данных, а его серверы находятся возле пользователей (CDN).

Роль сервера в ускорении представления контента напрямую зависит от веб-приложения. Решение не всегда сводится к «рендерингу целых страниц на сервере».

В некоторых случаях, неактуальную в данный момент для пользователя часть страницы лучше исключить из первоначального ответа и оставить на потом. Некоторые приложения, например, предпочитают осуществить рендеринг только «ядра» страницы для обеспечения немедленного отклика. Затем они запрашивают разные части страницы параллельно. Это обеспечивает лучшую отзывчивость даже в ситуации с медленным устаревшим бэкендом. Для некоторых страниц хорошим вариантом будет рендеринг только видимой части страницы.

Исключительно важна качественная оценка скриптов и стилей с учётом информации, которая у сервера есть о сессии, клиенте и URL. Скрипты, которые осуществляют сортировку заказов, очевидно будут важнее для /orders, чем логика страницы настроек. Может быть, не настолько очевидная, но есть разница в загрузке «структурного CSS» и «CSS для оформления». Первый может понадобиться для кода JavaScript, так что требуется блокировка, а второй загружается асинхронно.

Хороший пример SPA, которое не приводит к излишнему обмену пакетами, — концептуальный клон StackOverflow в 4096 байтах, он теоретически может загружаться с первым же пакетом после рукопожатия на TCP-соединении! Автор умудрился добиться такого за счёт отказа от кеширования, используя inline для всех ресурсов в ответе с сервера. Применив SPDY или HTTP/2 server push, теоретически возможно передать весь кешируемый клиентский код за один хоп. Ну а в настоящее время, рендеринг частей или всей страницы на стороне сервера остаётся самым популярным способом избавиться от лишних раундов обмена пакетами.

Proof-of-concept SPA с использованием inline для CSS и JS, чтобы избавиться от лишних roundtrip’ов

Достаточно гибкая система, которая разделяет рендеринг между браузером и сервером и предоставляет инструменты для постепенной загрузки скриптов и стилей, вполне может стереть грань между веб-сайтами и веб-приложениями. И то, и другое использует URL’ы, навигацию, демонстрирует данные пользователю. Даже приложение с электронными таблицами, которое традиционно полагается на функциональность с клиентской стороны, сначала должно показать клиенту информацию, которую требуется редактировать. И сделать это за наименьшее количество roundtrip’ов первостепенно важно.

С моей точки зрения, самый большой недостаток производительности во многих популярных системах в наше время объясняется прогрессивным накоплением сложности в стеке. Со временем добавлялись технологии вроде JavaScript и CSS. Их популярность тоже постепенно росла. Только сейчас мы можем оценить, как их можно использовать по-другому. Речь идёт и об улучшении протоколов (это показывает нынешний прогресс SPDY и QUIC), но наибольшую выгоду несёт всё-таки оптимизация приложений.

Полезно будет вспомнить некоторые исторические дискуссии вокруг дизайна ранних версий HTML и WWW. Например, этот список рассылки от 1997 года предлагает добавить тег <img> в HTML. Марк Андрессен повторяет, насколько важно быстро доставлять информацию:

«Если документ нужно составлять в единое целое на лету, то это может быть сколь угодно сложным, и даже если сложность ограничить, у нас всё равно возникнут крупные проблемы с производительностью из-за структуризации документов подобным способом. Прежде всего, это сразу нарушает принцип одного хопа в WWW (ну, IMG тоже его нарушает, но по очень специфической причине и в очень ограниченном смысле) — уверены ли мы, что хотим этого?»

2. Немедленный ответ на действия пользователя

tl;DR: JavaScript позволяет вообще спрятать сетевую задержку. Используя это как принцип дизайна, мы можем даже убрать из приложения почти все индикаторы загрузки и сообщения “loading”. PJAX или TurboLinks упускают возможности по увеличению субъективной скорости интерфейса. Наша задача состоит в максимальном ускорении реакции на действия пользователя. Сколько бы усилий мы не вкладывали в уменьшение числа хопов при работе с веб-приложением, но есть вещи вне нашего контроля. Это теоретический предел скорости света и минимальный пинг между клиентом и сервером.

Важный фактор — непредсказуемое качество связи между клиентом и сервером. Если качество связи плохое, то будет происходить повторная передача пакетов. Там, где контент должен загружаться за пару roundtrip’ов, может понадобиться гораздо больше.

В этом главное преимущество JavaScript для улучшения UX. Если на клиентской стороне интерфейс управляется с помощью скриптов, мы можем спрятать сетевую задержку. Мы можем создать впечатление высокой скорости. Мы можем искусственно достигнуть нулевой задержки.

Предположим снова, что перед нами обычный HTML. Документы соединяются гиперссылками или тегами <a>. Если нажать на любой из них, то браузер осуществит сетевой запрос, что занимает непредсказуемо долгое время, потом получает и обрабатывает полученные данные и наконец переходит в новое состояние.

JavaScript позволяет реагировать немедленно и оптимистично на действия пользователя. Нажатие на ссылку или кнопку приводит к немедленной реакции, без обращения в Сеть. Известный пример — это интерфейс Gmail (или Google Inbox), в котором архивация почтового сообщения происходит немедленно, тогда как соответствующий запрос к серверу отправляется и обрабатывается асинхронно.

В случае с формой, вместо ожидания какого-то кода HTML в качестве ответа на её заполнение, мы можем реагировать сразу, как только пользователь нажал “Enter”. Или даже лучше, как делает поиск Google, мы можем реагировать ещё раньше, готовя разметку для новой страницы заблаговременно.

Такое поведение — пример того, что я называю адаптацией разметки. Основная идея состоит в том, что страница «знает» свою будущую разметку, так что может переключиться на неё тогда, когда ещё нет данных для указания на это. Это «оптимистичное» поведение, потому что всё ещё остаётся риск, что данные никогда не поступят, и придётся выводить сообщение об ошибке, но это, очевидно, случается редко.

Заглавная страница Google вполне подходит в качестве примера, потому что она очень чётко демонстрирует первые два принципа из нашей статьи.

Во-первых, пакетный дамп TCP-соединения с www.google.com показывает, что они специально стараются отправить всю страницу целиком сразу после получения запроса. Весь обмен пакетами, включая закрытие соединения, занимает 64 мс для меня в Сан-Франциско. Вероятно, это было актуально для них с самого начала.

В конце 2004 года, компания Google стала пионером в использовании JavaScript для выдачи подсказок в реальном времени в процессе набора поискового запроса (интересно, что эту функцию сотрудник разработал в свободные от основной работы 20% времени, так же как и Gmail). Это даже стало фундаментом для появления Ajax:

Посмотрите на Google Suggest. Наблюдайте, как обновляются поисковые термины по мере набора текста, практически мгновенно… без задержки на перезагрузку страницы. Google Suggest и Google Maps — это два примера нового подхода к созданию веб-приложений, которые мы в Adaptive Path назвали “Ajax” И в 2010 они представили Instant Search, в котором JS играет центральную роль, вообще исключая обновление страницы вручную и переключаясь на разметку «поисковые результаты» при первом же нажатии клавиши, как видно на иллюстрации вверху.

Другой видный пример адаптации разметки, возможно, лежит у вас в кармане. С первых же дней iPhone OS требовала от авторов приложений предоставить картинку default.png, которое можно сразу вывести на экран во время загрузки самого приложения.

iPhone OS принудительно загружает default.png перед запуском приложения

В этом случае операционная система компенсирует не сетевую задержку, а CPU. Это было важно, учитывая производительность раннего оборудования. Правда, в некоторых случаях такой подход давал сбой. Например, если картинка не соответствовала экрану ввода пароля. Подробный анализ результатов публиковал Марко Армент в 2010 году.

Другим типом действий, кроме кликов и отправки форм, которые отлично улучшаются с помощью JavaScript, является рендеринг загрузки файла.

Мы можем зарегистрировать попытку пользователя загрузить файл разными способами: drag-n-drop, вставка из буфера, выбор файла. Затем, благодаря новым HTML5 APIs, мы можем отобразить контент, как будто он уже загружен. Пример такого рода интерфейса — наша работа с загрузками в Cloudup. Обратите внимание, как миниатюра изображения генерируется и рендерится мгновенно:

Изображение рендерится и отображается до окончания загрузки

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

Эта идея должна серьёзно повлиять на UI наших приложений. Я считаю, что индикаторы загрузки должны стать редкостью, особенно если мы переходим на приложения с информацией в реальном времени, которые описываются в следующем разделе.

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

Но даже в этих случаях, отображение на экране спиннеров или индикаторов загрузки следует прекратить. Их нужно отображать только после того, как пользователь считатиает отклик не мгновенным. В соответствии с часто цитируемым исследованием Nielsen:

Базовый совет по времени отклика остаётся неизменным уже тридцать лет Miller 1968; Card et al. 1991: * 0,1 секундs является лимитом, чтобы пользователь воспринимал отклик как немедленный, здесь не требуется отображение никакой дополнительной информации, кроме результата операции. * 1,0 секунды является лимитом на непрерывность потока мысли у пользователя, даже хотя он заметит задержку. Обычно, не требуется никакой дополнительной индикации при задержки более 0,1 секунды, но менее 1,0 секунды, но у пользователя пропадает ощущение прямой работы с данными. * 10 секунд является лимитом удерживания внимания пользователя на диалоге. При большей задержке пользователи захотят выполнить другую задачу, ожидая отклика от компьютера. Техники вроде PJAX или TurboLinks, к сожалению, упускают большинство возможностей, описанных в данном разделе. Код на клиентской стороне не «знает» о будущем состоянии страницы до тех пор, пока не состоится обмен данными с сервером.

3. Реакция на изменение данных

tl;DR: Когда на сервере обновляются данные, клиента следует уведомлять без задержки. Это такая форма повышения производительности, когда пользователя освобождают от необходимости совершать дополнительные действия (нажимать F5, обновлять страницу). Новые проблемы: управление (повторным) соединением, восстановление состояния. Третий принцип относится к реагированию UI на изменение данных в источнике, обычно, в одном или нескольких серверах баз данных.

Уходит в прошлое модель передачи по HTML данных, которые остаются статичными до тех пор, пока пользователь не обновит страницу (традиционные веб-сайты) или не взаимодействует с ней (Ajax).

Ваш UI должен обновляться автоматически.

Это критически важно в мире с нарастающим потоком информации из разных источников, включая часы, телефоны, планшеты и носимые устройства, которые появятся в будущем.

Представьте новостную ленту Facebook сразу после её появления, когда информацию публиковали, в основном, с персональных компьютеров пользователей. Статичный рендеринг нельзя было назвать оптимальным, но он имел смысл для людей, которые обновляли ленту, скажем, раз в день.

Сейчас мы живём в мире, когда ты загружаешь фотографию — и почти немедленно получаешь лайки и комментарии от друзей и знакомых. Необходимость в мгновенном отклике стала естественной необходимостью в конкурентном окружении других приложений.

Было бы неверным, однако, предположить, что преимущества мгновенного обновления UI ограничиваются только многопользовательскими приложениями. Вот почему я люблю говорить о согласованных дата-поинтах, вместо пользователей. Возьмём типичный сценарий синхронизации фотографии между телефоном и ваши собственным ноутбуком:

Однопользовательское приложение тоже может получить пользу от «реактивности»

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

Каждая страница реагирует на состоянии сессии и статус авторизации

Как только вы установили правило, что информация на экране обновляется автоматически, важно поработать над новой задачей: восстановление состояния.

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

Пример того, что происходит в случае некорректного обновления связи

Способность приложения нормально восстанавливать связь взаимодействует с принципом № 1. Если вы выбрали отправлять данные при первой же загрузке страницы, вы должны учитывать и время, которое прошло перед загрузкой скриптов. Это время, по существу, эквивалентно времени дисконнекта, так что первоначальное подключение ваших скриптов является возобновлением сессии.

4. Контроль обмена данными с сервером

tl;DR: Теперь мы можем тонко настраивать обмен данными с сервером. Убедитесь в обработке ошибок, повторных запросах в пользу клиента, синхронизации данных в фоновом режиме и сохранении кеша в офлайне. Когда появился веб, обмен данными между клиентом и сервером был ограничен несколькими способами:
  1. Нажатие на ссылку отправит GET для получения новой страницы и её рендеринга.
  2. Отправка формы отправит POST или GET с последующим рендерингом новой страницы.
  3. Внедрение изображения или объекта отправит GET асинхронно с последующим рендерингом.
Простота такой модели очень привлекательна, и сейчас всё определённо усложнилось, когда речь идёт о понимании, как получать и отправлять информацию.

Главные ограничения касаются второго пункта. Невозможность отправить данные без обязательной загрузки новой страницы было недостатком с точки зрения производительности. Но самое главное, что это полностью ломало кнопку «Назад»:

Вероятно, самый раздражающий артефакт старого веба

Именно поэтому веб как платформа для приложений оставался неполноценным без JavaScript. Ajax представлял собой огромный скачок вперед с точки зрения удобства в части публикации информации пользователем.

Сейчас у нас есть множество API (XMLHttpRequest, WebSocket, EventSource, это лишь некоторые из них), которые дают полный и чёткий контроль над потоком данных. Кроме возможности публиковать пользовательские данные через форму, у нас появились новые возможности по улучшению UX.

Прямое отношение к предыдущему принципу имеет показ состояния соединения. Если мы ожидаем, что данные будут обновляться автоматически, то обязаны информировать пользователя о фактах потери связи и попытках её восстановления.

При обнаружении дисконнекта, полезно сохранить данные в памяти (а ещё лучше, в localStorage), так что их можно отправить позднее. Это особенно важно в свете будущего использования ServiceWorker, который позволяет приложениям JavaScript работать в фоновом режиме. Если ваше приложение не открыто, вы всё ещё можете продолжать попытки синхронизировать данные с сервером в фоновом режиме.

Учитывайте возможность таймаутов и ошибок при отправке данных, такие ситуации должны решаться в пользу клиента. Если соединение восстановлено, пробуйте отправить данные снова. В случае постоянной ошибки, сообщите об этом пользователю.

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

Важно ещё убедиться, что пользователь случайно не прервёт поток данных. Это может случиться в двух ситуациях. Первый и самый очевидный случай — закрытие браузера или вкладки, что мы пытаемся предотвратить обработчиком beforeunload.

Предупреждение beforeunload

Другой (и менее очевидный) случай — попытка перехода на другую страницу, например, нажатие на ссылку. В этом случае приложение может остановить юзера иными методами, на усмотрение разработчика.

5. Не ломай историю, улучшай её

tl;DR: Если браузер не будет управлять URL’ами и историей, у нас возникнут новые проблемы. Убедитесь, что вы соответствуете ожидаемому поведению в отношении прокрутки. Сохраняйте собственный кеш для быстрого фидбека. Если не считать отправки форм, то при использовании в веб-приложении одних только гиперссылок у нас будет полностью функциональная навигация «Вперёд/Назад» в браузере.

К примеру, типичную «бесконечную» страницу обычно делают с помощью кнопки на JavaScript, которая запрашивает дополнительные данные/HTML и вставляет их. К сожалению, немногие при этом помнят о необходимости вызова history.pushState или replaceState как обязательного шага.

Вот почему я использую слово «ломать». С простой моделью первоначального веба такая ситуация была невозможна. Каждое изменение состояния основывалось на изменении URL.

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

Одну такую возможность Дэниел Пипиус назвал Fast Back:

Кнопка «Назад» должна работать быстро; пользователи не ожидают слишком большого изменения данных. Это как рассматривать кнопку «Назад» в качестве кнопки из веб-приложения и применить к ней принцип № 2: немедленно реагировать на действие пользователя. Главное, что у вас есть возможность решить, как организовать кеширование предыдущей страницы и мгновенно вывести её на экран. Вы можете затем применить принцип № 3, а потом информировать пользователя о поступлении новых данных на эту страницу.

Всё ещё остаётся несколько ситуаций, когда вы не можете контролировать поведение кеша. Например, если вы отрендерили страницу, затем ушли на сторонний сайт, а потом пользователь нажал «Назад». Этому маленькому багу особенно подвержены приложения, которые рендерят HTML на стороне сервера, а потом модифицируют его на стороне клиента:

Некорректная работа кнопки «Назад»

Ещё один способ сломать навигацию — игнорирование памяти о состоянии прокрутки. Ещё раз, страницы, которые не используют JS и ручное управление историей, скорее всего, не будут иметь тут проблем. Но динамические страницы будут. Я протестировал две самые популярные новостные ленты на основе JavaScript в интернете: Twitter и Facebook. У обоих обнаружилась амнезия на прокрутку.

Бесконечное листание страниц — обычно, признак скроллинг-амнезии

В конце концов, опасайтесь таких изменений состояния, которые релевантны только при просмотре истории. Например, этот случай с изменением состояния поддеревьев с комментариями.

Изменение вида комментариев нужно сохранять в истории

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

6. Обновление кода через push-сообщения

tl;DR: Недостаточно отправлять через push-сообщения только данные, нужно ещё и код. Избегайте ошибок API и повышайте производительность. Используйте stateless DOM для безболезненной перелицовки приложения. Исключительно важно, чтобы ваше приложение реагировало на изменения в коде.

Во-первых, это уменьшает количество возможных ошибок и повышает надёжность. Если вы сделали важное изменение в API бэкенда, то должны обновить код клиентских программ. В противном случае, клиенты могут не воспринять новые данные или могут прислать данные в несовместимом формате.

Не менее важной причиной является соблюдение принципа № 3. Если ваш интерфейс обновляется сам, то у пользователей мало причин обращаться к ручной перезагрузке страницы.

Имейте в виду, что у обычного сайта обновление страницы инициирует две вещи: перезагрузка данных и перезагрузка кода. Организация системы с push-обновлениями данных без push-обновлений кода неполноценна, особенно в мире, где одна вкладка (сессия) может оставаться открытой очень долгое время.

Если серверный push-канал работает, то пользователю можно выслать уведомление о доступности нового кода. Если нет, то номер версии можно добавить в заголовок исходящих HTTP-запросов. Сервер может сравнить его с последней известной версией, согласиться на обработку запроса или нет, и выдать задание для клиента.

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

Ещё лучший подход — «горячая» замена кода. Это значит, что не придётся осуществлять полную перезагрузку страницы. Вместо этого, определённые модули заменяются на лету, а их код повторно отправляется на выполнение.

Во многих существующих приложениях довольно сложно осуществить «горячую» замену кода. Для этого нужно изначально придерживаться архитектуры, которая разделяет поведение (код) от данных (состояние). Такое разделение позволит нам довольно быстро накатывать много разных патчей.

Например, в нашем веб-приложении есть модуль, который устанавливает шину для передачи event’ов (как socket.io). Когда событие наступает, состояние определённого компонента меняется и это отражается в DOM. Затем вы изменяете поведение этого компонента, например, так, что он генерирует разные разметки DOM для существующего и нового состояний.

В идеале у нас должна быть возможность менять код помодульно. Не нужно будет заново устанавливать соединение с сокетом, например, если есть возможность просто обновить код нужного компонента. Идеальная архитектура для push-обновлений кода, таким образом, является модульной.

Но сразу возникает проблема с тем, как оценить модули без нежелательных побочных эффектов. Здесь лучше всего подходит архитектура вроде той, которую предлагает React. Если код компонента обновляется, его логика может быть просто повторно исполнена, и DOM обновляется. Объяснение этой концепции от Дэна Абрамова читай здесь.

По существу, идея заключается в том, что вы обновляете DOM (или перекрашиваете его), что существенно помогает в замене кода. Если состояние сохранено в DOM или обработчики event’ов установлены приложением, то обновление кода может стать намного более сложной задачей.

7. Предсказание поведения

tl;DR: Отрицательная задержка. У современного JavaScript-приложения могут быть механизмы для предсказания действий пользователя.

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

Немного более продвинутый метод мониторинга отслеживания движения мыши анализирует её траекторию на предмет будущего «столкновения» с интерактивными элементами, как кнопки. Пример на jQuery:

Плагин jQuery предугадывает траекторию мыши

Заключение

Веб остаётся самой многогранной средой передачи информации. Мы продолжаем добавлять динамику на наши страницы и перед их внедрением должны убедиться, что сохраним важные принципы веба, доставшиеся нам в наследство.

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

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

habrahabr.ru

WEB приложение

При разработке WEB приложения можно использовать одну из наиболее популярных технологий, к которым следует отнести Java Servlets, Java Server Page, PHP, ASP.NET, Node.js. В статье приводятся преимущества и недостатки данных технологий при разработки Web приложения.

Web приложения реализуют бизнес-логику на стороне сервера и генерируют код для клиента. Т.е. клиент, как правило, является тонким, без каких-либо серьезных ресурсов обработки информации на сервере. Также у всех этих приложений одинакова архитектура взаимодействия сервера и клиента и общий протокол взаимодействия - HTTP.

Схематично логика работы WEB приложения представлена на рисунке.

Как следует из рисунка, работа приложений в облаке происходит в три основных этапа:

  • Запрос клиента. Браузер (клиент) инициирует запрос к серверной части WEB-приложения.
  • Обработка запроса сервером. После получения запроса сервер приложения проводит обработку запрашиваемой информации.Если запрашивается статический ресурс типа страницы HTML, рисунок, документ, то данная информация форматируется согласно протоколу HTTP и передается клиенту в качестве ответа.Если требуется динамический ресурс, то запрос передается на обработку соответствующему серверному приложению ("контейнеру" WEB приложения), где и происходит дальнейшая обработка параметров запроса.
  • Ответ клиенту. После обработки запроса и формирования ответа, данные передаются браузеру (клиенту) с использованием протокола HTTP. Ответ содержит данные (обычно в виде HTML кода, иногда двоичные данные), а также дополнительные параметры в заголовке HTTP ответа.

Данный подход к разработке приложений создает определенные сложности, основной из которых является отсутствие состояния WEB приложения (так называемое stateless programming). Это означает, что приложение работает исключительно в режиме запрос-ответ, не имея данных о предыдущих шагах пользователя или какой-либо иной постоянной информации. Для решения данной проблемы в различных WEB технологиях используется понятие пользовательской сессии, которая позволяет хранить определенную информацию на сервере в течение сеанса работы пользователя.

Однако наличие сложности разработки WEB приложения не ограничивается только сессией работы пользователя. Для ускорения разработки серьезных WEB приложений используются различные дополнительные фреймворки. Таким образом, чем больше возможностей предоставляет платформа, тем быстрее и эффективнее может вестись разработка.

Выбор технологии

Какую выбрать технологию для разработки WEB приложения целиком и полностью зависит от руководителя проекта (конструктора, разработчика). Можно, конечно, освоить новую, самую модную на текущий момент технологию, для расширения своего кругозора и разработки в ней еще одного приложения. Это особенно оправданно, если за все это платят хорошие деньги. Но чтобы стать после этого хорошим специалистом в данной области требуется значительное время.

Большой проект (WEB приложение) в конечном итоге может оказаться "провальным". Нет, не то, чтобы его не выполнили и не смогли сдать заказчику. Нет это все как раз со скрипом прошло успешно; ведь и заказчику порой нужно списать деньги, чтобы получить в следующем году не меньше. Но эта уже другая тема - как сдавать проект заказчику. Просто WEB приложением не стали пользоваться и оно умерло, не успев родиться.

В каком случае проект может оказаться неудачным, с чем это может быть связано? Может быть с неумелым управлением? Или с неправильным выбором платформы, о чем стало известно на последнем этапе. Причин может несколько, а виновных нет. Как известно, только у Побед много родителей, а вот Поражение всегда сирота.

Выбор конкретного подхода для разработки WEB приложения полностью зависит от руководителей проектов (конструкторов, разработчиков и т.п.), их опыта и знаний. Трудно сказать, что та или иная технология может решить все проблемы. У каждой есть определенные преимущества и недостатки.

В статье рассмотриваются различные подходы к созданию WEB приложений, их достоинства и недостатки, а также рассмотрены конкретные платформы. Использование различных подходов рассматривается с точки зрения построения сложных гетерогенных глобальных систем. Не все популярные технологии приводятся в данной статье.

Для различных платформ создания WEB приложений необходимо выделить два основных существующих подхода к разработке серверной части:

  1. Формирование кода в виде текста определенного формата.
  2. Встраивание кода в определенные шаблоны.

Первый подход предоставляет наибольшие возможности по повышению производительности. Он предусматривает передачу всех данных о запросе непосредственно серверу, который может как сформировать ответ со страницей для пользователя, так и открыть на передачу поток двоичных данных, например для передачи изображения. Однако при таком подходе все данные для передачи формируются программным путем, что замедляет разработку простых страниц. Примерами данног подхода являются технологии CGI, Java Servlets.

Второй подход использует оформленные особым образом шаблоны страниц, что позволяет вставлять в них участки кода. Этот подход особенно эффективен при создании WEB приложений, основная информация в которых статична, а динамическая информация может быть сгенерирована простыми программными конструкциями. При разработке больших систем этот вариант усложняет взаимодействие между компонентами и затрудняет реализацию сложной архитектуры. Также он менее эффективен по производительности и ограничивает возможности по реализации сложных страниц. Примерами данного подхода являются наиболее популярные на данный момент технологии PHP, ASP, JSP.

Наиболее важные требований, выдвигаемые при создании сложных Web систем, наличие которых делает систему привлекательной для использования:

  • платформная независимость;
  • язык реализации;
  • производительность, масштабируемость;
  • возможности расширения и интеграции;
  • простота использования, наличие средств разработки;
  • наличие необходимых программных библиотек;

Таким образом определены требования, необходимые для платформы разработки. Далее рассматриваются наиболее популярные на данный момент платформы, их особенности

Common Gateway Interface, CGI

Технология Common Gateway Interface (CGI) в отличии от остальных рассматриваемых технологий является наиболее низкоуровневой. Кроме этого данная технология является стандартом интерфейса, который служит для связи внешней программы с WEB сервером.

Протокол CGI разработан таким образом, чтобы можно было использовать любой язык программирования, который работает со стандартными устройствами ввода/вывода. Так как данная возможность присутствует на уровне операционной системы, то, если не требуется сложный скрипт, его можно оформить в виде командного файла.

Основные достоинства и недостатки технологии CGI :

CGI не налагает особых условий на платформу, поэтому работает на всех популярных платформах и WEB серверах. Также технология не привязана к конкретному языку программирования и может быть использована на любом языке, работающем со стандартными потоками ввода/вывода.

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

CGI программа представляет из себя готовый к исполнению файл, что препятствует легкому расширению системы.

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

Java Servlets

Технология Java Servlets (сервлеты) была разработана компанией Sun Microsystems, чтобы использовать преимущества платформы Java для решения проблем технологии CGI и API расширений сервера. Технология решает проблему производительности, выполняя все запросы как потоки в одном процессе. Сервлеты не зависят от платформы поскольку выполняются внутри Java Virtual Machine (JVM), и могут легко разделять ресурсы.

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

Сервлет является классом Java должен быть выполнен внутри Java VM. "Контейнер" WEB приложения типа Tomcat загружает класс сервлета при первом обращении к нему, либо сразу при запуске сервера согласно настройки конфигурации. Далее сервлет остается загруженным для обработки запросов, пока он не выгружается явным образом, либо до остановки контейнера.

Технология сервлетов является распространенной и может быть использована со всеми популярными WEB серверами, выполняющими функции контейнера сервлетов (Apache Tomcat, Java Web Server от Sun).

Программный интерфейс позволяет сервлетам обрабатывать запросы на низком уровне (заголовки запросов, их тип, и т.д). Это обеспечивает большую гибкость при разработке нестандартных обработчиков, например при работе с двоичным или мультимедийным содержимым.

В связи с тем, что сервлеты обрабатываются в одном процессе с помощью создания внутри него потоков, программный код сервлетов должен быть потокобезопасным. Это накладывает определенную ответственность на программиста. При этом сервлеты приобретают такое неоценимое преимущество как масштабируемость.

Таким образом, сервлеты обеспечивают компонентный, платформонезависимый метод построения WEB приложений без ограничений производительности. Они имеют широкий диапазон доступных прикладных API, позволяют использовать все преимущества Java, легко расширяются и масштабируются, поддерживаются всеми популярными WEB серверами. Все это обеспечивает использование данной технологии для разработки крупных WEB систем.

Java Server Page, JSP

Технология Java Server Pages (JSP) от компании Sun Microsystems является надстройкой над технологией Java Servlets, обеспечивающая более быструю и простую разработку WEB приложений с помощью использования шаблонов. Для понимания архитектуры и преимуществ JSP необходимо знать технологию Java Servlets, поскольку они тесно связаны.

Страницы JSP представляют из себя шаблоны страниц, схожие с шаблонами РНР и ASP. Основным отличием от других подобных технологий является то, что код, находящийся внутри страницы, предварительно компилируется в Java Servlet. Статические участки шаблона преобразуются в вызовы к функциям для их помещения в поток вывода. Код компилируется так, как если бы он находился внутри сервлета. Компиляция JSP страниц в сервлеты проводится один раз - либо при первом обращении к странице, либо при запуске контейнера сервлетов.

Технология JSP удачно объединяет все преимущества Java платформы b шаблонный подход к построению сайтов. Благодаря этому технология получила широкое распространение как среди профессиональных коммерческих разработчиков, так и при создании открытых бесплатных проектов.

Важным шагом к расширению шаблонного подхода стали так называемые библиотеки тэгов (tag libraries). Это гибкая возможность интегрировать стандартные, сторонние, или собственные программные компоненты в страницы. Простота создания и использования привели к большой популярности библиотек тэгов.

Технология JSP не привязана к конкретной аппаратной или программной платформе благодаря работе на основе Java. То есть JSP являются отличным решением для использования в гетерогенных средах.

Производительность технологии ограничена объективными особенностями архитектуры. Во-первых, страницы должны быть откомпилированы в сервлеты, но только один раз при первом к ним обращении. Во-вторых сервлеты выполняются в JVM, т.е. в режиме интерпретации. Однако эти ограничения компенсируются дополнительными возможностями. Так современные WEB "контейнеры" поддерживают кластеризацию серверов, что перекладывает нагрузку на аппаратное обеспечение. Это является экономически оправданным и простым решением.

Основными достоинствами JSP является простота разработки, характерная для шаблонного подхода, наличие большого количества сторонних библиотек, легкость их использования, мощные и разнообразные среды разработки. Благодаря всем этим факторам JSP является наиболее перспективной базовой технологией разработки при создании Web - сайтов. Однако при создании сложных WEB систем ограничения, накладываемые шаблонным подходом становятся серьезным препятствием к развитию.

Personal Home Page, PHP

Технология Personal Home Page (PHP) получила широкое распространение благодаря поддержке самых популярных платформ своей и бесплатности. Она базируется на принципе построения страниц на основе шаблонов. Страницы РНР имеют вид обычных HTML страниц, в которые могут быть включены специальные тэги вида <?php?>. Между тэгами вставляются строки программного кода на специальном языке сценариев РНР.

Основные достоинства и недостатки платформы PHP :

  • Применяемый в РНР язык прост и удобен, однако не является в полном смысле объектно-ориентированным; Для РНР существуют обширные библиотеки, а также масса встроенных функций для решения самых разнообразных задач.
  • При использовании РНР с Web сервером Apache есть возможность эффективного исполнения ядра, как расширения сервера. В остальных случаях производительность платформы невысока. Собственных средств масштабирования РНР не имеет, все возможности по кластеризации целиком ложатся на WEB сервер и разработчиков.
  • Возможности интеграции ограничены включением модулей и использованием внешних функций, что не соответствует современным требованиям.

Хранение всего кода в файлах-страницах приводит к затруднению разделения бизнес-логики и интерфейса при создании больших систем.

Тем не менее можно заключить, что, благодаря простоте использования, наличию большого числа функций и библиотек, распространенности и поддержке большинства существующих WEB серверов и платформ, РНР является очень удобным средством разработки небольших систем. В то же время ограничения по производительности, масштабируемости, языку программирования и возможностям расширения и интеграции препятствуют использованию платформы при разработке масштабных систем.

Технология Microsoft .NET и среда ASP.NET

Технология .NET является последней разработкой компании Microsoft и заявлена как новый этап в развитии средств взаимодействия между приложениями. В настоящий момент она доступна в качестве дополнения .NET Framework к семейству операционных систем Microsoft Windows. Также продолжаются работы по созданию и совершенствованию технологии .NET Framework на других операционных системах.

Основой .NET является Common Language Runtime (CLR общая среда исполнения языков), опирающаяся на системные службы операционной системы и управляющая выполнением кода, написанного на любом языке программирования. Набор базовых классов дает доступ к сервисам платформы, которые можно использовать при программировании. CLR и базовые классы вместе составляют основу .NET платформы.

NET предлагает такие высокоуровневые сервисы для разработки WEB приложений как :

  • ASP .NET - новая версия ASP, позволяющая использовать любой (.NET совместимый) язык для программирования Web страниц;
  • Windows Forms и Web Forms - набор классов для построения пользовательского интерфейса локальных и WEB-ориентированных приложений.

Важной составляющей частью платформы .NET является обновленная среда ASP.NET (ранее использовалось ASP+). В ее основе лежит новая платформа, и основными языками программирования для нее выбраны С# и Visual Basic, вместо бывших скриптовых языков. В то же время, новая технология позволяет писать ASP страницы на любом подходящем языке программирования.

В технологию ASP.NET заложено все, чтобы сделать весь цикл разработки WEB приложения более быстрым, а поддержку проще. Основные возможности ASP.NET.

  1. Компилирование кода при первом обращении.
  2. Широкий выбор библиотек компонентов, поставляемых с .NET.
  3. Поддержка среды разработки Visual Studio.NET.
  4. Языковая независимость в пределах платформ для которых реализована общая языковая среда исполнения.
  5. Возможности расширения с помощью мультипроцессорных и кластерных решений.
  6. Новые возможности по обработке ошибок.
  7. Объектно-ориентированные языки разработки (С#).

Вместе с созданием технологии ASP.NET появились новые возможности по разработке WEB систем, отвечающие всем современным требованиям и позволяющие значительно ускорить и упростить разработку сложных приложений. Однако ASP.NET сильно привязана к серверу IIS, и, хотя архитектура .NET позволяет перенести приложения ASP.NET на другую платформу, на данный момент реальная возможность отсутствует.

Таким образом, многоплатформенность пока еще не может быть удовлетворена платформой .NET. Однако необходимо отметить, что такая система должна иметь возможности интеграции с платформой .NET (особенно WEB сервисы).

Node.js

Согласно Википедии Node или Node.js — это серверная реализация языка программирования JavaScript, основанная на движке V8. Предназначена Node для создания масштабируемых распределённых сетевых приложений, таких как WEB сервер. В отличие от большинства программ с использованием JavaScript, Node.js исполняется не в браузере клиента, а на стороне сервера.

Несомненно, Node.js и JavaScript имеют существенные отличия. В первую очередь Node.js - это платформа для разработки веб приложений, а JavaScript - это язык. Опять же под JavaScript подразумевают скрипт, выполняемый на стороне клиента (в браузере), а Node.js выполняется на сервере. То есть, Node.js просто другой контекст : он позволяет запускать JavaScript-код вне браузера.

Чтобы код JavaScript выполнился вне браузера (на backend), он должен быть интерпретирован. Именно это и делает Node.js. Для этого он использует движок V8 от Google — ту же самую среду исполнения для JavaScript, которую использует браузер Google Chrome.

Основные недостатки Node.js

1. Отсутствие полноценной IDE. Существуют плагины для Eclipse и NetBeans, есть частичная поддержка и в других IDE, но назвать их полноценными решениями на данный момент нельзя. Особый интерес представляет Cloud9 IDE для разработки на JavaScript прямо в браузере. Эта IDE быстро развивается и уже активно используется многими Node.JS разработчиками.

2. Необходимость перезапуска приложения после внесения изменения. Несмотря на существование утилит, автоматизирующих данный процесс, некоторое время на это всё равно уходит. Для сравнения, при использовании шаблонного подхода для разработки интерфейса (JSP, PHP) перезапуск приложения не требуется. Но если вносятся изменения к примеру в JavaBean или servlet, то также потребуется перезапуск WEB-приложения, и происходит это намного дольше.

Контроль за уечкой памяти. С этим сталкиваются начинающие Node.JS. За памятью надо следить всегда и везде, но быстро живущие PHP-скрипты или небольшой клиентский JavaScript сильно расслабляют. В таких приложениях многие разработчики особо не предают значения потере нескольких килобайт памяти, а некоторые вообще не следят за этим показателем. Node.JS таких поблажек не делает. Приложение на Node.JS работает долго, и в случае утечки, каждый запрос к сайту будет уносить с собой кусочек памяти, которая очень быстро закончится, что приведёт к известным последствиям. Специфика JavaScript также располагает к появлению этого типа ошибок.

Возврат ошибок из асинхронного кода. Например, в PHP весь код выполняется синхронно, поэтому отловить ошибку на любом уровне вложенности можно с помощью конструкции try-catch. Но в Node.js большая часть кода работает асинхронно (операции ввода/вывода). При этом исключительные ситуации, как правило, возникают не при вызове метода, а при работе его callback'а, который выполняется уже вне конструкции try-catch. Для передачи информации об ошибках в Node.JS принято использовать первый параметр callback-функции. Т.е. если у нас возникла ошибка, мы вызываем callback-функцию либо с одним единственным параметром, описывающем её, либо первый параметр выставляем в undefined/null, а в последующих передаём результаты работы нашего функционала. В реальных приложениях вложенность вызовов может быть довольно большой и каждый раз передавать ошибку наверх очень неудобно.

Сложные математические расчёты не для Node.JS. Конечно, можно и на велосипеде привезти кирпичи для дома. Но зачем? Так и в Node.JS всё же возможно производить сложные математические расчёты, путём разбиения задачи на короткие итерации, выполняемые за несколько витков event loop, но это уже извращения и фанатизм. Гораздо проще выносить такие задачи за пределы event loop или вообще выбрать другую технологию для разработки.

Достоинства Node.js

Асинхронный ввод/вывод. Это самое значимое преимущество Node.js и оно лежит в основе данной технологии. В Node.js можно одновременно выполнять несколько операций, не зависящих друг от друга. При синхронном выполнении, например в PHP, операции будут выполняться друг за другом последовательно, каждый раз ожидая завершения предыдущей. В Node.js запросы к СУБД можно отправить «параллельно». На самом деле запросы отправляются последовательно , но Node.JS не дожидается результата работы предыдущего запроса, чтобы отправить следующий. По мере выполнения запросов, будут вызваны callback-функции для обработки их результата.

Использование асинхронного ввода/вывода к примеру в JSP потребует включение в приложение дополнительной библиотеки jQuery, которая позволяет осуществлять Ajax-запрос к серверу без перезагрузки страницы.

Один и тот же язык на сервере и на клиенте. Это позволяет повторно использовать некоторый код для валидации форм, построения шаблонов на клиенте и т.п. В целом, это очень упрощает разработку, особенно, когда клиентская часть приложения сложная и требует серьёзной работы.

Обработка http-запроса внутри себя. Это значит, что для каждого нового запроса не выполняется инициализация, как, например, на PHP. Настройки загружены, соединения с БД и с кешем открыты, код скомпилирован и готов к работе. Благодаря такой архитектуре и гибкости открывается огромный простор для различных техник оптимизации. Например, один раз разобрав шаблон, можно хранить его в виде функции, принимающей на вход данные и возвращающей готовый HTML. Или можно легко организовать локальное (для процесса) кеширование, наиболее часто используемых данных, что даст прирост в скорости работы с ними.

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

Сам язык JavaScript и API Node.js очень гибкие и лаконичные. Программы получаются компактными и легко читаемыми. Вы вряд ли увидите в них классы, состоящие практически целиком из геттеров и сеттеров, или десятки файлов с описаниями интерфейсов. Такие вещи, как замыкания и лямбда-функции, позволяют писать очень красивый код.

java-online.ru

Разработка веб-приложений

Технология "world wide web" появилась лишь немногим позже, чем получили распространение сами персональные компьютеры, её начало скрыто в далеком 1989 году. В 21 веке появилось множество различных платформ – это и Windows, и Linux, и Mac, и мобильные устройства – но все они имели общее свойство – их пользователь должен "ходить в Интернет" и видеть одинаковое содержимое веб-сайтов на любой платформе. Поэтому WWW – это самая распространенная и по-настоящему кросс-платформенная технология в мире.

Чем веб-приложение отличается от веб-сайта?

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

С появлением нового стандарта HTML 5, веб-приложения стали настолько же мощными и функциональными, как программы Windows или мобильные приложения для Android или iOS. На сайтах, следующих стандарту HTML 5, можно использовать всю мощь оконного пользовательского интерфейса, использовать звуковые и видеоэффекты, использовать картографию и даже определять местоположение пользователя.

Есть важный нюанс:

Приложение не обязательно связано с сайтом

Сайт находится в Интернете и доступен публично (или по паролю). А приложение может быть установлено и в локальной сети предприятия, и даже на отдельном компьютере. Конечно, на отдельном компьютере ставить его вряд ли имеет смысл, ведь у технологии www есть важное преимущество:

Веб-приложение легко реализует многопользовательскую работу

Разработка веб-приложений ведется, как правило, с использованием языка JavaScript, исполняемого прямо в браузере, и с использованием любого языка программирования со стороны сервера. Наиболее популярные языки программирования – PHP, Microsoft.NET C# и Java. Наша команда использует для разработки язык Java, что связано, во-первых, с лучшей архитектурой Java-приложений, чем, например, проектов на PHP, а во-вторых, с тем, что, в отличие от C#, Java – кросс-платформенная среда разработки и не привязана к дорогостоящим серверным решениям от Microsoft.

Пример веб-приложения

"Сделайте мне базу данных"

Эти слова произносит нам практически каждый заказчик. "База данных", точнее, интерфейс для работы с таблицами данных – это стандартное и самое, наверное, распространенное приложение. Оно позволяет добавлять, просматривать, изменять и удалять данные (такое приложение иногда называется CRUD – Create, Read, Update, Delete). Конечно, с данными можно делать и любые другие действия – импортировать, экспортировать, отправлять по почте.

Более сложными веб-приложениями являются сервисы работы с картографией, составления статистических отчетов, блоги и интернет-магазины, а также административные модули для Android и iOS-приложений.

Преимущества веб-приложений

В отличие от desktop-приложений (обычных программ, устанавливаемых на компьютер), веб-приложения (программы-сервисы, Software as a Service, SaaS) более удобны как для пользователя, так и для обслуживающей организации, так как они обладают преимуществами:

  • Возможность работы многих пользователей. Каждый пользователь может иметь свой личный кабинет на сайте, при этом права пользователей могут различаться, а сами пользователи могут быть распределены по организациям (корпоративным учетным записям).
  • Автоматическое обновление. Веб-приложение всегда имеет одинаковую версию и одинаковый вид для всех пользователей - это удобно как для технической поддержки, так и для самих пользователей, которые всегда пользуются наиболее актуальной версией.
  • Доступ с любого устройства. Пользователь может пользоваться веб-сайтом с любого компьютера, ноутбука, планшета или даже сотового телефона, из любой точки мира.
  • Защита от потери данных. Данные пользователей хранятся в "облаке", целостность которого поддерживается хостинг-провайдерами, таким образом, данные защищены от случайной утери при повреждении жесткого диска компьютера.

К преимуществу веб-приложения следует отнести и

возможность регулярного получения дохода от пользователей,

если вы разрабатываете веб-приложение для публичного доступа. Как правило, модель монетизации веб-приложения включает в себя свободную регистрацию пользователей с бесплатным ограниченным доступом, и ежемесячные платежи ("подписка") пользователей "премиум-аккаунта" с расширенными функциями. Многие платежные системы, с которыми можно интегрировать приложение, предоставляют услугу автоматических ежемесячных платежей (то есть,

пока пользователь не откажется от услуг, с его банковского счета будут ежемесячно автоматически списываться средства).

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

Процесс разработки

Разработка веб-приложения, по сути, ничем не отличается от разработки под iOS или Android – работа начинается с анализа требований заказчика, затем инженеры занимаются проектированием, дизайном пользовательского интерфейса и кодированием, после чего результат работы тестируется и сдается заказчику.

Стоит отметить особенность, связанную с многообразием устройств, поддерживающих веб-платформу.

Веб-приложение может иметь Desktop-дизайн и мобильный дизайн

Оптимизация веб-сайта для мобильных устройств является одним из важных факторов, принимаемым во внимание поисковыми системами при ранжировании сайтов. Мы используем при разработке технологию Bootstrap, автоматически создающую как минимум два варианта дизайна пользовательского интерфейса – для компьютеров и мобильных телефонов.

Интеграция с другими системами

При разработке приложения часто возникает требование его взаимодействия с другими подсистемами, например, SMS-шлюзом, платежной системой или социальными сетями. При разработке на Java и JavaScript эта проблема легко решается, поскольку программный интерфейс (API) уже встроен в архитектуру программ, написанных на этих языках программирования. Конечно, при наличии интеграции процесс разработки и тестирования усложняется, но это не вызовет непредвиденных трудностей у наших инженеров.

Готовы заказать разработку?

Мы предлагаем Вам:

  • разработку и дизайн веб-приложений
  • интеграцию веб-приложений с SMS-сервисами и другими системами
  • разработку административных модулей для Android- и iPhone-приложений
  • разработку нагруженных веб-приложений

Заполнить бриф

 

Смотрите также

Как подготовить требования к приложению? >>

Посмотреть портфолио >>

www.headwind.ru

Проектирование и разработка корпоративных web приложений / Хабрахабр

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

    На следующем этапе необходимо собрать требования к приложению, которое необходимо разработать. Уточнить цели и область решаемых задач и построить иерархическую структуру работ.

    Рассмотрим отдельно задачу построения иерархической структуры работ. Каждое web-приложение можно представить в следующем виде:

    Другими словами, каждое web-приложение отправляет http запросы на web-сервер для получения полезных данных. Программа под управлением web-сервера использует ту или иную модель для хранения данных. В современном мире чаще всего используются базы данных, SQL или NoSQL.

    Формально каждое web-приложение можно разбить на 3 взаимно независимые части.

  1. Модуль, который исполняется WEB-браузером. Это приложение может быть написано на любом языке, который поддерживает браузер. Чаще всего используется язык JavaScript, как наиболее поддерживаемый и имеющий большую библиотечную поддержку. Это очень важно, так как позволяет существенно экономить бюджеты проектов.
  2. Модуль, исполняемый на серверной стороне под управлением web-сервера. Это приложение может быть написано на любом языке, интерпретацию которого поддерживает выбранный Вами web-сервер. Последнее время, часто, в качестве языка программирования выбирается язык Java. Этот язык также имеет серьезную библиотечную поддержку.
  3. База данных. В этой области так же существует достаточно широкий выбор. Есть промышленные базы данных, такие как Oracle, DB2, PostgreSQL. Есть легкие базы данных, такие как MySQL. База данных выбирается основываясь на целях и области решаемых задач.

      Возможные эталонные модели проектирования web-приложений.

    При построении архитектуры web — приложения необходимо максимально уменьшить зависимость между структурными единицами. В общем случае приложение состоит из трех структурных единиц.

  1. Модуль, который работает под управлением браузера.
  2. Модуль, который работает под управлением web-сервера.
  3. База данных.

Эти структурные единицы порождают два вида связей.

  1. Связь между браузером и серверной частью.
  2. Связь между серверной частью и базой данных.

    Для достижения цели максимальной независимости между структурными единицами, необходимо чтобы каждая структурная единица оперировала только необходимым ей набором данных. Рассмотрим более подробно.

    Браузер — это прикладное программное обеспечение для просмотра web страниц.

    HTML – это стандартный язык разметки документов. Большинство современных web-браузеров способны интерпретировать язык HTML.

    Web сервер — это программное обеспечение, которое способно принимать HTTP запросы от клиентов, обрабатывать их и отправлять ответ в соответствии со стандартом протокола.

    База данных — это представленная в объективной форме совокупность самостоятельных материалов, систематизированных таким образом, чтобы эти материалы могли быть найдены и обработаны с помощью ЭВМ.(Wiki)

                                    Минимизация зависимостей

    Для минимизации зависимостей между «Браузером» и Web-сервером необходимо, чтобы язык разметки HTML был задействован только в браузере, а Web-сервер предоставлял интерфейс для получения необходимых данных для страницы.

    Для решения этой задачи необходимо:

  • Определить цели и область решаемых задач, которые будут решаться в рамках создаваемого интерфейса.
  • Определить API серверной части.
  • Выбрать протокол взаимодействия между серверной и клиентской частью. Создание протокола удобнее всего выбрать на базе XML, так как большинство современных браузеров имеют встроенную поддержку этого языка.
  • Написать документ, в котором будет изложен протокол.
    Наша диаграмма может быть преобразована в следующий вид:

    Далее «Браузер» преобразуется в UML диаграммы состояний. На этих диаграммах будет отражено, в каком случае вызывается тот или иной метод.

Данная модель достижима двумя путями

  1. Программа выполняемая «Браузером» написана на JavaScript и общается с Web-Сервером через AJAX, получая ответы в соответствие с определенным протоколом.
  2. «Браузер» интерпретирует только HTML код, а преобразования происходят посредством XSLT преобразований на стороне Web-Сервера.

    В каждом из этих случаев достигается разделение программной части Web-Сервера и «Браузера». Т.е используя данную модель возможно вносить изменения в структурную единицу для «Браузера» и не вызывать косвенных изменений в серверной части. Это очень важно, так как ведет к уменьшению затрат на обработку запросов на изменения. Это происходит в силу того, что изменения в одной структурной единицы не выходят за ее рамки.

                    Взаимодействие Web-Сервера и Базы данных

    Взаимодействие базы данных и web-сервера возможно организовать на основании двух принципиально разных сценариях:

  1. Бизнес логика находится в базе данных.
  2. Бизнес логика находится в коде web-сервера.

    В первом случае база данных хранит данные и предоставляет интерфейс доступа к данным:

  1. Выборка данных — решается через представления.
  2. Модификация данных — решается через хранимые процедуры.

    Программа для web-сервера является драйвером для доступа к бизнес-логике. Т.е она просто связывает Браузер с бизнес логикой, которая реализована в базе данных.

    Во втором случае база данных хранит данные, и предоставляет прямой доступ к данным. Бизнес-логика реализована в коде web-сервера. В этом случае база данных предоставляет транзакции для проведения атомарных операций.

    Для минимизации зависимостей между Web-Сервером и Базой данных, необходимо, чтобы бизнес-логика была определена только в одном месте. Т.е либо в коде Web-Сервера, либо в Базе данных. Это очень важно, так как ведет к уменьшению затрат на обработку запросов на изменения. Это происходит в силу того, что изменения в одной структурной единицы не выходят за ее рамки.

                                Иерархическая структура работ

    На основании изложенного выше материала иерархическая структура работ примет следующий вид:

  1. Модуль для «Браузера».
  2. Модуль для Web-Сервера.
  3. Модуль для Базы данных.
  4. Протокол обмена между модулем «Браузера» и Web-Сервером.
  5. Интерфейс взаимодействия между модулем «Браузера» и Web-Сервером.
  6. Интерфейс взаимодействия между Web-Сервером и Базой данных.

habrahabr.ru

Разработка веб-приложений и веб-сервисов на C++. Как это правильно делать.

Веб-фреймворки и Веб-сервера

Итак, веб-сервисы и веб-приложения создаются, как правило, не на С++. Любой другой язык предоставляет массу качественных веб-фреймворков: у Python есть Django, Flask, Tornado; у PHP есть Symfony; у Javascript (Node.js) есть Express; у Java есть Spring Web MVC; у Erlang есть N2O и так далее. Это отличные решения, которые, в первую очередь, позволяют программисту не погружаться в протокол HTTP (RFC2616), а сразу сосредоточиться на бизнес-логике своего приложения. Многие веб-фреймворки имеют в своем составе реализацию ORM, что упрощает работу с базами данных. Кроме этого, веб-фреймворки предоставляют:

  • диспетчеризацию URL;
  • систему шаблонов, для удобного создания html-страниц;
  • средства для интернационализация и локализации;
  • авторизацию и аутентификацию;
  • и многое другое.

Но одного веб-фреймворка не достаточно для создания веб-сервиса, понадобится еще, как минимум, веб-сервер. В мире не так много веб-серверов, заслуживающих внимание. Это Apache HTTP server, Nginx, lighttpd, Tornado, Node.js, Yaws, Netty. Веб-серверов существует меньше, чем веб-фреймворков, и новые появляются значительно реже (Caddy). Зачем же нужен веб-сервер, если есть веб-фреймворк?

Веб-сервер - это надежная, быстрая, потребляющая небольшое количество ресурсов программа. Веб-сервер способен поддерживать одновременное подключение тысяч клиентов, и не терять при этом работоспособность. Веб-сервер отлично справляется с такими задачами как: шифрование данных (SSL termination), сжатие данных, обслуживание статических запросов, кеширование, балансировка нагрузки и так далее. Веб-фреймворки не касаются решения этих задач. Эти задачи не являются их зоной ответственности. Фактически, установив и настроив веб-сервер на прием запросов из внешнего мира, мы снимаем огромный "пласт" работы с веб-фреймворка (который "как бы спрятан" за веб-сервером). Например, ему больше не обязательно "быть готовым" встретить тысячи пользователей. Вместо этого, мы можем развернуть 20 веб-фреймворков за одним веб-сервером, и тонко настроить балансировку нагрузки.

То, что веб-сервер необходимо выбирать именно из числа выше названных, подтверждается крупнейшими компаниями - Яндекс, Google, Facebook, Bloomberg, Amazone - какой бы веб-фреймворк не использовался этими компаниями, неизменным остается то, что никто не пишет свой веб-сервер. Обычно, берут либо Nginx, либо Apache. И это первое, что нам нужно уяснить - при разработки веб-приложения на С++, нам также потребуется веб-сервер из числа названных.

Зачем писать веб-приложение на С++

Возможно, вы программист С++ и другие языки вам не знакомы. Возможно, в компании не разрешают писать на чем-либо кроме С++, а сделать свой веб-сервис необходимо по ТЗ. Ситуации бывают разные, и говорить, что С++ для этого совершенно не подходит не правильно.

Есть одна, но очень веская причина разрабатывать back-end веб-сервиса на С++ - любой интерпретируемый язык (будь то Python с его несчастным GIL-ом, Ruby, PHP и другие) проиграет  С++ в быстродействии и потреблении ресурсов. Хорошо написанная, и оптимизированная компилятором, программа на С++ будет работать не хуже аналогичного варианта на С. Если, высокая эффективность для вас не главное требование, то возможно С++ не стоит брать для разработки веб-сервиса. Писать на С++ однозначно придется больше и дольше. Однако, есть вы хотите получить максимум КПД от своих вычислительных мощностей (которых всегда не хватает), то вам придется перейти на компилируемый язык. И С++ тут отличный и хорошо знакомый всем кандидат (языки Go и Rust еще не завоевали такой популярности, а Java и C# могут оказаться избыточными для микросервиса). 

Итак, веб-приложение или веб-сервис будем разрабатывать именно на С++.

Почему не нужно писать свой Веб-сервер на Asio

Я очень много разрабатываю с использованием Asio и добиваюсь очень эффективных результатов. Миллионы сообщений переданных по сети в течении всего одной секунды, сериализованных и  зашифрованных. Asio - это отличная библиотека! Но она не подходит для того, чтобы делать на ней веб-сервер... Почему? Ответ - это слишком низкоуровневый подход. Конечно, возможно у вас получится написать эффективный, быстрый и надежный код. Но сколько на это уйдет времени? И будет ли это решение в итоге быстрее, чем Nginx? И главное, как вы будете решать вопрос функциональных возможностей? Давайте просто сравним, что дает нам Asio, и что предлагает его "Java аналог" - Netty:

Asio C++ Library

Netty framework

Сразу скажу, что поддержка SSL и TLS в Asio хуже, чем у Netty. По сути, вам придется напрямую работать с OpenSSL, так как ASIO предоставляет весьма условные классы-обертки. Здесь можно было бы обойтись и вовсе без Asio, так как вся работы возлагается на OpenSSL. Но шифрование в данном случае не главное.

Обратите внимание на протоколы. Asio заканчивается на уровне TCP. Дальше вам всё нужно будет написать самим. Скорее всего потребуются дополнительные библиотеки, чтобы, например, обеспечить сжатие данных в протоколе HTTP, чтобы поддержать протокол Web-сокетов. В конце концов, чтобы просто получить веб-сервер, соответствующий протоколу HTTP/1.1. Ведь в С++ нет даже стандартной библиотеки для парсинга URL (кто считает это ерундой, тот не парсил арабские линки). Всё это вы либо возьмете из внешних библиотек, либо будете очень долго писать сами, либо (что хуже всего) откажетесь вовсе поддерживать (сказав - мне это не нужно).

Какой бы путь вы не выбрали с Asio, вы потеряете очень много времени, и не приблизитесь к решению именно вашей задачи. Вы просто будете писать свой веб-сервер, который в лучше случае сможет работать также надежно и быстро, как Nginx. И который в лучшем случае поддержит хотя бы 10% от того, что сразу идет в базовой конфигурации любого существующего веб-сервера. Вы удовлетворите только собственное желание "попробовать сделать самому". Пишите на Asio то, что нельзя взять в готовом варианте. Веб-сервер же установите Nginx. На это у вас уйдет 1 минута, и 10 минут, чтобы сконфигурировать его работу.

Почему не нужно брать Веб-сервер на Qt, POCO, Wt C++ или cpp-netlib

К этому моменту мне, возможно, уже удалось отговорить вас писать веб-сервер самостоятельно. Но как насчет Qt? POCO? Wt? Или cpp-netlib? Последняя библиотека, кстати, использует Asio. Все перечисленные инструменты - это C++, а не Java/Python/C. Они имеют хорошие функциональные возможности, готовые реализации веб-серверов, и даже предлагают себя в качестве веб-фреймворков. Как, к примеру, Wt (у Wt на борту есть Bootstrap 2 и 3, что кажется уже перебором). Казалось бы на С++ есть всё готовое. Бери и используй. Но не спешите...

Вот один из многочисленных бенчмарков HTTP-серверов, опубликованный на Хабре. Смотрим результаты: POCO медленнее Nginx-а всего лишь в 5 раз, cpp-netlib медленнее в 20 раз! И вот вопрос: зачем тянуть в проект большие внешние библиотеки, которые изначально хуже, чем тот же Nginx? Nginx активно развивается на протяжении более десяти лет (как и Apache или lighttpd). Повторить эту работу не просто даже специализированным библиотекам. Отмечу, что все перечисленные C++ библиотеки, также уступают в функциональности тому же Apache. Для Apache сообщество на протяжении длительного времени написало такое количество подключаемых модулей, что их трудно все перечислить. 

В итоге, если вы пишете свой веб-сервис или веб-приложение на С++, вам лучше использовать в качестве веб-сервера Nginx, Apache или lighttpd. При чем не нужно компилировать и линковать код этих веб-серверов вместе со своим кодом. Эти сервера должны быть установлены "штатно", как и любые другие программы, и работать самостоятельно. Нам же остается только найти решение, как "подружить" программу на С++ с внешним веб-сервером. И решение здесь очень простое.

SCGI и FastCGI - способ подружить Веб-сервер и программу на C++

Если эти технологии вам не знакомы, то прочитайте о них на Википедии. В двух словах - это клиент-серверные протоколы взаимодействия веб-сервера и приложения (в нашем случае С++ приложения). Эти два протокола являются дальнейшим развитием протокола CGI. Однако, CGI работает медленно, и лучше этот подход не рассматривать.

FastCGI-приложения используют Unix Domain Sockets или TCP/IP для связи с веб-сервером. Первый вариант менее гибкий, но более быстрый. Второй вариант, это обычное сетевое клиент-серверное взаимодействие. И здесь (внимание) есть смысл применить свои навыки в Asio, и написать эффективный транспорт для общения с веб-сервером! Потому что, только это от вас и требуется. 

Nginх "встретит" запрос пользователя, расшифрует его, определит куда следует направить дальше этот запрос, и передаст его вашему приложению на С++. Дождется ответа от вашего приложения, сожмет и зашифрует данные, а затем передаст их пользователю. Масштабировать такое решение очень легко - просто запустите столько копий FastCGI-приложения сколько потребуется (на разных машинах или на одной), настройте балансировку в Nginx и всё!

С вашего приложения снимается огромная работа, а в замен вам нужно поддержать на выбор FastCGI или SCGI. Тут есть два подхода - либо взять готовые решения, либо совместить, к примеру, свой транспорт на Asio и "чистый" парсер того же протокола SCGI. Кстати, SCGI реально реализовать одному программисту всего за несколько дней в полном объеме (с нуля).

В любом случае, вашей работы теперь существенно меньше, а результат просто отличный - это и настоящий веб-сервер, через который не страшно смотреть в мир, и простое масштабирование, и высокая скорость работы. Это надежный проверенный способ, о котором много написано статей, в том числе и на Хабре (здесь и здесь).

В итоге, что мы имеем. При разработке веб-сервиса или веб-приложения на С++ нам нужен внешний хороший веб-сервер, а наша программа на С++ должна поддержать протокол взаимодействия с выбранным веб-сервером - FastCGI или SCGI. Двигаемся дальше: как помочь себе в создании веб-фреймворка на С++.

Как помочь себе в создании веб-фреймворка на С++

Я против написания веб-сервера, но, я "за" написание собственного веб-фреймворка. Вот только рутинную работу, нужно на кого-то переложить. А самим написать самое "вкусное" - тот же диспетчер URL, на шаблонах, с созданием своего DSL (как же без этого). А что значит - рутинная работа?

В начале я описывал, что делает веб-фреймворк, и что делает веб-сервер. Задачи этих двух компонентов не пересекаются (обычно). Веб-сервер мы взяли готовый (например, Nginx), а в своей программе поддержали SCGI, но работа на этом не закончилась. Нам нужно добавить себе в программу те возможности, которые обычно предоставляются веб-фреймворками. И здесь целесообразно использовать по максимум готовые решения.

Например, нам потребуется очень много парсить... В начале нужно парсить URL - задача абсолютно стандартная. Решений очень много - от могучих парсеров по типу Google's URL parsing library​, до минималистичных библиотек в один исходный файл. Затем, потребуется парсить передаваемые сообщения - это могут быть и данные форм, и Json-данные, и xml-данные. Но тут уже всё зависит от вашего сервиса. Вы, например, вольны отказаться от использования в REST-протоколе формата XML. И тогда парсер xml вам будет не нужен.

Вторая задача, это "общение" с базой данных. Как и в случае с парсерами, вам нужно будет выбрать решение на С++, исходя из потребностей. Если это "традиционная" база данных, возможно вам подойдет SQLAPI++ Library. Если вы используете какую-либо NoSQL базу, то существуют соответствующие клиенты на С++ и для них (например, для MongoDB).

Несколько слов про ORM. Задумайтесь, так ли он нужен в вашем микросервисе? ORM полезен в том случае, когда ваше приложение достаточно большое и совершает много простых запросов к базе. В этом случае, ORM скрывает всю эту "кухню". Но если ваш микросервис делает всего 10-20 различных запросов к базе, то не стоит создавать весь этот overhead под названием ORM. Это всегда влечет дополнительные накладные расходы. Кроме того, вы лишаете себя возможности оптимизировать каждый из запросов. Лучше напишите эти запросы один раз, и забудьте про ORM. ORM, особенно "самописный", скорее мешает в дальнейшем сопровождении кода, чем помогает. SQL знаком очень многим, а ORM - это обычная "вкусовщина".

Сейчас популярны так называемые "микрофреймворки". В них отсутствует такие возможности как: 

  • система рендеринга html-шаблонов
  • ORM, и в принципе средства доступа к базам данных
  • различные плагины авторизации, аутентификации, роли, работа с email

Всё это легко подключается, если есть такая необходимость. Этому принципу и надо следовать. То что действительно нужно, у вас уже есть - это полноценный безопасный быстрый веб-сервер со всеми его возможностями, библиотеки для разбора URL и JSON, какой-либо драйвер к базе данных. Возможно на этом и следует остановиться. Объединить все компоненты и вашу бизнес-логику в красивое быстрое решение на С++.

Итак. При разработке веб-сервиса или веб-приложения на С++ нам нужен хороший веб-сервер, набор небольших микро-библиотек для парсинга URL, и тех форматов данных, которые будут передаваться, и возможно драйвер для базы данных. Также нам нужно поддержать протокол  FastCGI или SCGI в своей программе на С++. Всё. 

Заключение

Решение, которое вы получите в итоге будет в первую очередь эффективным, надежным и гибким. Все компоненты, от веб-сервера до парсеров, вы сможете в любой момент заменить на более подходящие. Ваши бенчмарки будут показывать отличные результаты, лучше и выше, чем у POCO или cpp-netlib. При этом ваши возможности по масштабированию и расширению функционала не будут ничем ограничены. Нужно интегрировать систему рендеринга html - без проблем, внедрить LDAP аутентификацию - без проблем. Если ничего из этого не нужно - то ваш веб-сервис будет по-настоящему "микросервисом", и никакого лишнего кода.

Предложенный в этой статье подход не является чем-то новым, скорее наоборот. Спецификация на FastCGI появилась кажется еще в 90-х. В это время появились и веб-сервера, которые поддерживали протокол FastCGI. В подтверждение своих слов привожу ссылку на интересную лекцию от Яндекса: Архитектура высоконагруженного сервиса на примере бэкенда Яндекс.Store. Обратите особое внимание на 8-ой слайд. На нем вы увидите всё о чем было написано в этой статье. 

Спасибо за внимание!

P.S.: если будет интересно, я мог бы выложить на github пример небольшого микросервиса построенного по описанному в статье подходу (с конфигурационными файлами для какого-либо веб-сервера). Всё будет написано конечно на С++.

artlang.net


Смотрите также