Asp проектирование веб приложений, использующих транзакции


Содержание

Изучение шаблонов проектирования Web-сервисов, Часть 1

Асинхронные операции Web-сервисов с использованием JMS

Серия контента:

Этот контент является частью # из серии # статей: Советы по программированию Web-сервисов

Этот контент является частью серии: Советы по программированию Web-сервисов

Следите за выходом новых статей этой серии.

Если представить себе реализацию Web-сервисов с SOAP, скорее всего, вам придут в голову простые синхронные операции типа запрос-ответ. На самом деле Service-Oriented Architecture (SOA) может охватывать гораздо больший диапазон моделей обмена сообщениями и стратегий проектирования. В данном документе мы сфокусируемся на применении основных шаблонов проектирования Web-приложений с использованием Web-сервисов. Представляемые шаблоны не являются новыми, они используются в традиционных Web-приложениях уже много лет, однако многие разработчики даже не подозревают о том, как реализовать такие методики в области Web-сервисов или же не до конца понимают, как их применять. Автор ставит перед собой задачу представления набора простых, открытых альтернатив проектирования модели запрос-ответ. Для изучения примера вам необходимо иметь хотя бы основные представления о реализации Web-сервисов в среде J2EE.

Шаблон асинхронного запроса

Чтобы отбросить лишнее, мы исследуем реализацию асинхронных операций запросов и ответов с целью разбиения длительных операций, и для того чтобы избежать тайм-аутов или долгих отбоев при выполнении кода. Если вы обладаете опытом реализации асинхронных запросов в традиционных Web-приложениях HTTP и HTML, применяемый шаблон должен быть вам знаком.

Рисунок 1. Шаблон асинхронного запроса

Поток в данной модели весьма прост:

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

О применении данного шаблона в приложениях сервлетов J2EE для Java Ranch (Web-сайта Java-разработчиков) написана превосходная статья, автором которой является Kyle Brown (См. Ресурсы по теме). В данной статье, кроме всего прочего, обсуждаются мотивации и основные вопросы проектирования касательно базовой реализации данного шаблона. Не удивительно, что реализация не сильно изменилась в шаблоне, применимом для Web-сервисов.

Проектирование интерфейса сервиса

Для иллюстрирования шаблона асинхронного запроса мы реализуем простой пример Web-сервиса, который вне этого примера не имеет особого практического значения. Данный сервис выполняет простое преобразование трех входящих значений типа String из нижнего регистра в верхний после применения 10-ти секундной задержки (для симуляции длительных процессов).

Для реализации данного сервиса доступны две операции: submitRequest и checkResponse . Действие этих операций не требует объяснения. В Листинге 1 представлен WSDL, описывающий интерфейс сервиса.

Листинг 1. AsyncService.wsdl

Здесь следует отметить несколько моментов:

  1. Сервис использует стиль написания кода RPC/Literal.
  2. Обе операции submitRequest и checkResponse возвращают объект с именем Response . Существует две разновидности Response , определяемые свойством типа (type property). Значение свойства типа равное 0 указывает на Refresh Response, а значение 1 — на Request Response. Refresh Response указывает на то, что ответ еще не доступен и запрашивающая сторона должна подтвердить новую операцию checkResponse не ранее, чем указано в значении свойства обновления (эквивалентно механизму HTTP META Refresh , обсуждаемому в статье Kyle Brown). Request Response содержит три строки ввода в верхнем регистре и представляет завершение обработки запроса.
  3. Refresh Response содержит свойство Correlation ID , чье значение используется в качестве ввода для операции checkResponse . Данный идентификатор является единственным средством для сопоставления клиентом начального запроса с ответом. Существуют также и другие способы для этой реализации, о которых будет рассказано позднее.

В Листинге 2 представлен типичный обмен сообщениями для данного сервиса.

Листинг 2. Обмен сообщениями AsyncService

Реализация сервиса

Реализацией сервиса асинхронного шаблона запроса является применение Java Messaging Service. Для иллюстрации примера здесь используется OpenJMS – реализация поставщика JMS с открытым исходным кодом (см. Ресурсы по теме) и IBM® WebSphere® Application Server V5 (сервер приложений). В примере используется конфигурация OpenJMS, определенная по умолчанию, а также реализация Web-сервиса J2EE, совместимого с JSR-109. Код для данного примера написан с использованием WebSphere Studio Application Developer (Application Developer) V5.1, который можно загрузить по ссылке с сайта developerWorks (см. Ресурсы по теме). Здесь также прилагается EAR-файл (см. Ресурсы по теме) на тот случай, если у вас нет доступа к Application Developer.

На стороне сервера необходимо реализовать два компонента – обработчик запросов и реализация Web-сервиса. Задачей обработчика запросов является снятие запросов из очереди и выполнение 10-секундной задержки процесса по преобразованию нижнего регистра символов в верхний. Задачей реализации сервиса является получение запросов от клиентов Web-сервиса и постановка их в очередь для обработки и для доставки ответов клиентам, следуя операции checkResponse.

В типичном приложении J2EE, согласно спецификации JMS, обработчик запросов должен быть реализован как Message Driven Bean (компонент, управляемый сообщениями). В данном примере используется простой HTTP-сервлет, реализующий JMS-интерфейс MessageListener . Сервлет настроен на инициализацию при загрузке сервера, что позволяет слушателю быть доступным для всех возможных входящих запросов. После постановки запроса в очередь тот доставляется сервлету-слушателю.

Листинг 3. JNDIListenerServlet.java

Сервлет JNDIListenerServlet и реализация сервиса используют один простой вспомогательный класс, созданный для этого приложения, который скрывает детали инициализации JMS-соединения и сессии.

Листинг 4. JNDIHelper.java

После создания сервлета отредактируйте файл Web-приложения web.xml таким образом, чтобы сервлет инициализировался при загрузке сервера. При инициализации сервлет создает JMS-соединение и регистрирует себя в качестве слушателя в очереди сообщений OpenJMS, заданной по умолчанию.

Вторым шагом является создание реализации сервиса. Здесь может пригодиться работа с Application Developer, который может помочь в генерировании различных артефактов для получения работающего JSR-109 Web-сервиса. Теперь сфокусируемся исключительно на классе реализации сервиса. Для иллюстрации других различных файлов конфигураций Java и XML к данному документу прилагается исходный код, который может быть загружен по ссылке в конце документа.

Листинг 5. AsyncService.java

В этом листинге нет ничего необычного. Метод submitRequest подготавливает JMS MapMessage на базе входящих параметров. Это сообщение состоит из трех строковых значений. После этого сообщение отправляется в очередь и подготавливается Refresh Response содержащий ID корреляции, после чего тот возвращается клиенту.

Операция checkResponse принимает ID корреляции из входных параметров и устанавливает соединение с очередью ответа, запрашивая доставку любых сообщений с соответствующим ID корреляции. Если таких сообщений не существует, операция не ждет их, а подготавливает другой Refresh Response с новым периодом интервала обновления и возвращает его обратно запрашивающей стороне. Если сообщение доставлено, операция подготавливает и возвращает соответствующий Request Response.

Для запуска Web-сервиса асинхронного шаблона запроса необходимо разместить Web-сервис и запустить серверы OpenJMS и WebSphere.

Выводы

Основным преимуществом шаблона асинхронных запросов является возможность корреляции запросов и ответов клиентом Web-сервисов и поставщиком сервиса. В представленном здесь примере был рассмотрен простой ID корреляции однократного использования и механизм обновления таймера, присущего этому отдельному примеру приложения. Для этой же цели можно использовать, к примеру, несколько комбинаций WS-* спецификаций. WS-Addressing Endpoint Reference или WS-Transaction Coordination Context также могут содержать ID корреляции и обновлять значения таймера. Использование данного шаблона индивидуально для отдельных приложений, и независимо от того, используете ли вы стандартные элементы заголовка SOAP и различные WS-* спецификации, поведение каждой реализации операции должно быть четко определено и задокументировано.

В реализуемом здесь примере для отправки запросов и получения ответов используется традиционный шаблон обмена сообщениями SOAP типа запрос-ответ. В качестве альтернативы можно использовать шаблон в стиле REST, в которой запросы отправляются сервлету методом HTTP POST, а ответы извлекаются с использованием метода HTTP GET. Каждый из этих подходов является в равной степени допустимым и обладает собственными преимуществами и недостатками. Выбор подхода осуществляется в зависимости от требования вашего приложения. Например, если операция checkResponse будет требовать использования аутентификации WS-Security, то в использование модели взаимодействия в стиле REST нет смысла.

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

Ресурсы для скачивания

  • этот контент в PDF
  • ws-tip-altdesign1ear.ear»>Размещенный EAR-файл WebSphere (ws-tip-altdesign1ear.ear | 701 KB)
  • ws-tip-altdesign1code.zip»>Исходники программы-примера (ws-tip-altdesign1code.zip | 719 KB)

Похожие темы

  • Оригинальная статья «Learn simple, practical Web services design patterns, Part 1»
  • Другие документы из серии «Практическое обучение использованию шаблонов Web-сервисов»:
    • Изучение шаблонов проектирования Web-сервисов, Часть 2
    • Изучение шаблонов проектирования Web-сервисов, Часть 3
    • Простые и полезные модели проектирования Web-служб, часть 4
  • Статья, рассказывающая о шаблоне асинхронных запросов «Asynchronous Queries in J2EE», где представлены теоретические основы, необходимые для обсуждения шаблонов асинхронных запросов. публикована на сайте Java Ranch, автор Kyle Brown.
  • Ссылка на загрузку программы WebSphere Studio Application Developer, используемой для написания данного примера приложения.
  • Ссылка на информацию о программе с открытым исходным кодом OpenJMS provider.
  • Книжный магазин Developer Bookstore, содержащий сотни книг о Web-сервисах.
  • Множество информативных статей и руководств по разработке приложений Web-сервисов в разделе SOA и Web-сервисы на developerWorks Россия.
  • Ссылки по теме:
    Изучение шаблонов проектирования Web-сервисов, Часть 2
    Изучение шаблонов проектирования Web-сервисов, Часть 3
    Простые и полезные модели проектирования Web-служб, часть 4

Комментарии

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

Полезные советы по оптимизации ASP-приложений

Введение

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

Публикуемый ниже материал представляет собой первый совет из целой серии советов по оптимизации приложений, использующих технологии ASP и Visual Basic Scripting Edition (VBScript). Большинство из них были многократно обсуждены и c успехом проверены на веб-сайте Microsoft Corporation и других ASP-сайтах. Авторы материала подразумевают, что вы уже знакомы с основами разработки ASP-приложений, включая VBScript и/или JScript, ASP-сессиями и др. важными объектами (Request, Response и Server).

Кэшируйте часто используемые данные на сервере

Типичная ASP-страница получает данные из базы данных и затем выводит их в формате HTML. Независимо от скорости вашей базы данных, получение данных из памяти сервера намного быстрее, чем обработка sql-запроса к конечной базе данных. Получение данных, сохраненных на локальном жестком диске, также обычно быстрее, чем получение информации из БД. Поэтому одним из основных путей увеличения скорости работы вашей ASP-страницы является кэширование часто используемой информации в памяти или на жестком диске.

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

Данные, которые не изменяются часто, являются хорошим кандидатом для кэширования, потому что вам не надо будет волноваться относительно их синхронизации через какое-то время с конечной базой данных. Выпадающие списки (сombo-box), таблицы ссылок, пункты меню, и переменные конфигурации сайта (включая имена DSN, адреса IP и URL) — первые кандидаты для хранения в кэше. Заметьте, что вы можете кэшировать представление данных много быстрее, нежели данные сами себя. Если ASP-страница изменяется не так часто и ее временный кэш будет весьма внушительным (например, полный каталог изделий фирмы), попробуйте использовать сгенерированные HTML-страницы, чем каждый раз загружать сервер генерацией ASP-страниц.

Кэшируйте часто используемые данные в объектах Application или Session

Объекты Application и Session служат для хранения данных в памяти, значения которых могут быть доступны между несколькими HTTP-запросами (в отличие от обычных переменных, чьи значения доступны только в теле одной ASP-страницы). Данные объекта Session доступны только одному пользователю (в течении его сессии), в то время как данные Application доступны всем пользователям веб-сайта. Поэтому часто перед разработчиком возникает вопрос: в каком из объектов сохранять часто используемые данные. Обычно, для инициализации переменных этих объектов используются процедуры файла Global.asa — Application_OnStart() или Session_OnStart() соответственно. Если в вашем Global.asa еще нет этих процедур, то вы можете добавить их сами или инициализировать переменные, когда это будет необходимо. Примером может быть следующая процедура, использующая Application для хранения значений многократно использующейся переменной EmploymentStatusList. Процедура проверяет существование данных в EmploymentStatusList и при необходимости расчитывает их заново:

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

‘Сохранить значение recordset в виде массива

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

‘Сохранить значение recordset в виде HTML-списка

Кэшируйте данные на диске веб-сервера

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

Заметьте, что при измерении производительности одиночной ASP-страницы, получение данных с диска может не всегда быть быстрее, чем получение равноценных данных из БД. Но «файловое» кэширование уменьшает загрузку БД и сети, а при высокой загрузке БД до, значительно улучшит общую производительность после. Кэширование может быть очень эффективно при кэшировании результатов сложных запросов (например, соединение таблиц), трудоемких процедур сохранения, больших наборов записей. Чтобы убедится, насколько выгодным будет это решение требуется протестировать различные схемы сохранения.

ASP и COM обеспечивают несколько инструментальных средств для создания схем кэширования на диске. Функции набора записей ADO Save() и Open() сохраняют и загружают recordset c диска. Используя эти методы вы можете переписать код из прошлого совета, заменяя запись в объект Application на метод Save() для записи в файл.

Есть несколько других компонентов, которые работают с файлами:

* Scripting.FileSystemObject позволяет создавать, читать и записывать файл.
* MSXML, MicrosoftR XML parser поддерживает сохранение и загрузку XML-документов.
* Объект LookupTable (например, используемый на MSN.com) — лучший выбор для загрузки простых списков с диска.

Наконец, рассмотрите вопрос принудительного кэширования информации на диске. Сгенерированный HTML-код может быть сохранен на диске как .htm или .asp файл; гиперссылки могут указывать прямо на этот файл. Вы можете автоматизировать процесс генерации HTML, используя коммерческие инструментальные средства типа XBuilder или средства публикации в Интернет, входящие в MicrosoftR SQL ServerT. Кроме того, при помощи директивы #include можно включать отдельные HTML-части в файл ASP или читать HTML-файл с диска используя FileSystemObject. Например, на начальной странице vbCode (http://vbcity.com/vbcode/ru/home.asp) приводятся 10 последних тем обсуждения двух дискуссионных форумов. Отобразить эти списки можно при помощи создания двух наборов записей ADO при каждом обращении к данной странице или, следуя данному совету, сохранить их однажды в виде HTML-файла list.inc, а затем включать в home.asp:

Второй путь работает значительно быстрее.

Избегайте кэшировать медленные компоненты в объектах Application или Session

Несмотря на то, что кэшированиe данных в объектах Application или Session может быть хорошей идеей, кэширование COM-объектов может иметь серьезные ловушки. Занесение наиболее используемых COM-объектов в объекты Application или Session часто соблазняет, но, к сожалению, много COM-объектов, включая все, написанные в Visual Basic 6.0 или ранее, могут вызывать серьезные критические проблемы после сохранения в объектах Application или Session.

В частности, любой компонент, который выполняется медленно, вызовет критические проблемы когда кэшируется в объектах Session или Application. Быстрый (проворный non-agile) компонент — компонент, помеченный ThreadingModel=Both, который объединен Free-threaded marshaler (FTM), или — компонент, помеченный ThreadingModel=Neutral. (Neutral — новая модель в WindowsR 2000 and COM+). Следующие компоненты не проворны:

* Free-threaded components.
* Apartment-threaded components.
* Single-threaded component.
* Configured components (библиотека Microsoft Transaction Server (MTS)/COM+ и серверные приложения) не проворны пока они Neutral-threaded. Apartment-threaded components и другие не проворные компоненты хорошо работают в пределах страницы (т.е. создаются и разрушаются в пределах одной ASP-страницы).

В IIS 4.0 компонент, отмеченный ThreadingModel=Both выполняется быстро. В IIS 5.0 уже не так достаточно. Компонент не должен только быть отмечен как Both, он должен также объединен FTM.

IIS выполняет проверку компонентов, но если вы хотите ее отменить (т.е. хотите позволить непроворным компонентам быть сохраненными в объектах Application или Session), вы можете установить AspTrackThreadingModel в metabase в значение True. Но это (изменение AspTrackThreadingModel) не рекомендуется.

IIS 5.0 выдаст сообщение об ошибке, если Вы пытаетесь сохранить непроворный компонент, созданный с использованием Server.CreateObject, в объекте Application. Вы можете обойти это, используя в Global.asa, но это также не рекомендуется, поскольку это ведет к проблемам (очереди и сериализация), объясняемым ниже.

Что же все-таки неправильно если вы кэшируете непроворные компоненты? Непроворный компонент, кэшируемый в объекте Session блокирует Session от других рабочих потоков (thread) ASP. ASP обслуживает пул (контейнер) рабочих потоков, запрашиваемых другими сервисами. Обычно, новый запрос обрабатывается первым доступным потоком. Если Session блокирована, то запрос должен ждать поток, когда он станет доступным. Проведем аналогию, которая поможет понять эту ситуацию: вы идете в магазин, выбираете несколько булок, и платите за них в кассе #3. Всякий раз, после того как вы выбрали булки в том магазине, вы всегда оплачиваете их в кассе #3, даже в том случае, когда в других кассах короче очередь или даже вообще нет покупателей.

Сохранение непроворных компонентов в объект Application накладывает столь же негативный эффект на производительность. ASP создает специальный поток для выполнения меделенных компонентов в пределах Application. Это имеет два последствия: все запросы выстраиваются в очередь к этому потоку и все запросы сериализуются. Выстраивание в очередь означает, что параметры были сохранены в общедоступной области памяти; запросы переключаются к специальному потоку; метод компонента выполнен; результаты выстраиваются в общедоступную область. Сериализация (преобразование в последовательную форму) означает, что все методы выполняются в одно время. Для двух различных потоков ASP не возможно одновременное выполнение методов общедоступного компонента. Это уничтожает многопотоковость (параллелизм), особенно на мультипроцессорных системах. Хуже всего то, что все непроворные компоненты в пределах Application совместно используют один поток («Host STA»), так что негативные результаты сериализации налицо.

Смущены? Есть некоторые общие правила. Если Вы пишете объекты в Visual Basic (6.0 или ранее), не храните их в объектах Application или Session. Если вы не знаете потоковую модель объекта, не храните его в кэше. Вместо кэширования где-либо непроворных объектов, вы должны создать и удалить их на каждой странице. Объекты выполнятся непосредственно в рабочем потоке ASP и не будет никакой очереди или сериализации. Производимость будет адекватна, если COM-объекты запущены под IIS и если они не используют много времени, чтобы инициализироваться и уничтожаться. Заметьте, что однопотоковые (single-threaded) объекты не должны использоваться этот путь. Будьте внимательным — VB может создавать однопотоковые объекты! Если вы используете однопотоковые объекты, этот путь (типа таблицы Microsoft Excel) не рассчитывает на высокую производительность.

Наборы записей (recordset) ADO могут безопасно кэшироваться когда ADO отмечен как Free-threaded. Чтобы сделать ADO как Free-threaded используйте файл Makfre15.bat, который обычно зафиксирован в каталоге Program FilesCommon FilesSystemADO.

Предупреждение: ADO не должен быть Free-threaded, если вы используете Microsoft Access в качестве БД. Набор записей ADO должен быть также вообще отсоединен, если вы не можете управлять конфигурацией ADO на вашем веб-сайте.

Не кэшируйте соединение БД в объектах Application или Session

Кэширование соединений ADO — обычно плохая стратегия. Если один объект Connection сохранен в объекте Application и используется на всех страницах, то все страницы будут бороться за использование этого соединения. Если объект Connection сохранен в ASP-объекте Session, то соединение БД будет создано для каждого пользователя. Это создает излишнюю загрузку веб-сервера и БД.

Вместо кэширования соединений БД, создавайте и уничтожайте объекты ADO на каждой ASP странице, которая использует ADO. Это эффективно, потому что IIS имеет встроенное подключение БД. Более точно, IIS автоматически допускает объединение подключений OLEDB и ODBC. Это гарантирует, что создание и уничтожение связей на каждой странице будут эффективны.

Так как соединенные наборы хранят ссылки на подключение БД, это следует, что вы должны не кэшировать соединенные наборы в объектах Application или Session. Однако, вы можете безопасно кэшировать отсоединенные наборы, которые не держат ссылку на подключение. Чтобы отсоединить набор записей, сделайте следующие два шага:

Подробную информацию относительно подключений смотрите в справочниках по ADO и SQL Server.

Разумное использование объекта Session

Теперь, когда в предыдущих советах были раскрыты достоинства кэширования данных в объектах Applications и Sessions, мы собираемся предложить вам избегать использования объекта Session. Сессии имеют несколько ловушек когда используются на загруженных сайтах. Под «загруженными» имеются ввиду сайты с сотнями запрашиваемых страниц в секунду или тысячами пользователей одновременно. Этот совет также важен для сайтов, которые должны масштабироваться горизонтально — т.е. те сайты, которые используют несколько серверов для распределения нагрузки и обеспечения отказоустойчивости при сбоях. Для меньших сайтов, типа intranet-сайтов, преимущества применения Sessions все же перевешивают.

Обобщая, ASP автоматически создает Session для каждого пользователя, который обращается к веб-серверу. Каждая сессия занимает приблизительно 10 Кб памяти (сверх любых данных, сохраненных в Session) и немного замедляет выполнение всех запросов. Сессия остается действующей до окончания таймаута (timeout), обычно 20 мин.

Но самая большая проблема при использовании сессий — это не производительность, а расширяемость. Сессии не охватывают все задействованные веб-сервера; как только Session была создана на одном сервере ее данные остаются там. Это означает, что если вы используете сессии на мультисерверном веб-сайте, вы должны придумать стратегию для обработки запросов каждого пользователя, которые должны быть всегда направлены на сервер, на котором существует сессия этого пользователя. Это называется «застреванием» пользователя на сервере (или «липкой сессией»).

Объект Application также не охватывает все сервера: если вам нужно совместно использовать и обновлять данные Application через веб-сервера, вам нужно использовать конечную базу данных. Однако неизменяемые (read-only) данные Application все же полезны на мультисерверных сайтах.

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

Если же вы не используете Session, то убедитесь, что отключили их. Это можно сделать посредством Internet Services Manager (см. документацию по ISM). Но если вам все-таки необходимо использовать сессии, то есть несколько путей уменьшить их удары про производительности.

Вы можете переместить содержимое, которое не требует сессий (например, страницы help и т.д.) в отдельное ASP-приложение, у которого сессии выключены. Кроме того, на страницах, где объект Session не используется, применяйте следующую директиву, помещещаемую вверху страницы:

Одна из основных причин ее применения — то, что Session создает интересную проблему в случае использования фрэймов (frameset). ASP гарантирует, что в любое время будет выполняться только один запрос от Session. Это делается для того, чтобы при одновременном запросе одним пользователем нескольких страниц, только один ASP-запрос был обработан сессией, что помогает избежать проблем многопоточного доступа к объекту Session. К сожалению, в результате этого все страницы в frameset будут загружаться последовательно, а не одновременно, и пользователю придется продолжительное время ждать полной загрузки. Мораль этой истории: если вы не уверены, что с использованием фрэймов и Session ваше приложение правильно работает, то используйте:

Альтернативой использованию объекта Session являются многочисленные параметры управления Session. При передаче малых объемов данных (менее 4 Кб) обычно рекомендуется использовать Cookies, переменные QueryString и скрытые (hidden) переменные форм. При использовании большого количества передаваемых параметров (например, корзина произведенных заказов в он-лайн магазине) наиболее лучший выбор — конечная база данных.

Разработка web-приложений с использованием технологии ASP.Net MVC

Web-приложения разработанные по технологии ASP.Net MVC в отличии от Web Forms приложений, состоят не из набора классов производных от класса Раде (web-форм), которые включают серверные элементы управления, а из классов трех типов:

  • контроллеры (Controller) – классы, включающие методы (действия), которые могут быть вызваны с помощью запроса пользователя к приложению;
  • представления (View) – задаются в виде шаблона, на основе которого генерируются специальные классы описывающего формирование HTML-ответы пользователю;
  • модели классы разных типов, содержащие данные, которые передаются от контроллеров в представления для формирования ответов.

Особенность технологии MVC состоит в том, что пользователь указывает в URL-адресе не путь к физическому ресурсу (например, *.html или *.aspx), а запрос на выполнение некоторого действия – открытого (public) метода класса-контроллера. Например: myprog.ru/Home/lndex/5 (такому URL никакой ресурс не соответствует). Порядок обработки таких запросов классами MVC-приложения показан на рис. 4.23.

Рис. 4.23. Порядок обработки запроса к MVC-приложению

Общая логика работы ASP.Net MVC приложения показана на рис. 4.24.

Рис. 4.24. Логика работы ASP.Net МVС приложений

Если сравнить данную схему с логикой работы ASP.Nel Web Forms приложений (рис. 4.1), то видно, что они во многом сходны (это два фреймворка технологии ASP.Net). У приложений, созданных с использованием фреймверков ASP.Net Web Forms и MVC, имеются общие возможности: конфигурирование; обеспечение безопасности (классы по работе с учетными записями и ролями); поддержка состояния сеанса и приложения; кэширование. В принципе, в одной приложении можно использовать возможности обоих фреймверков.

Отличие ASP.Net Web Forms и MVC между заключается только в использовании другого МТТР-обработчика. Данный обработчик создает требуемый контроллер и вызывает указанный метод.

В ASP.NET MVC разработчик имеет почти те же самые функциональные возможности по созданию web-приложений, какие есть и в Web Forms, но они реализуются с помощью другого набора инструментов. Фреймвер ASP.NET MVC использует другой шаблон, который не основывается на web-формах (Раде) и полагается на много более тонкий слой абстракции. В результате у разработчика нет сложных, встроенных компонент для быстрого создания пользовательского интерфейса, в котором элементы могут поддерживаться.

В ASP.NET MVC разработчик пишет код, который концептуально и физически ближе к базовым Интернет технологиям; поэтому он требует большего объема программирования, но в тоже время дает ему больше контроля над формируемым FITML-кодом и реальным поведением среды выполнения приложения. Однако, разработчик не должен все писать с нуля. Он имеет в своем распоряжении

  • • HTML-помощьники (helpers) для автоматического создания (достаточно) простых, но функциональных средств визуализации и редактирования для любых простых и сложных типов;
  • • атрибуты классов (дополнительные метаданные) для аннотирования данных, для декларативного задания требуемого содержания полей и способов их представления;
  • • средства связывания для автоматического преобразования передаваемых в запросе данных с параметрами методов-действий контроллеров;
  • • средства (тоже на основе атрибутов) для проверки вводимых пользователями данных, как на стороне клиента, так и на стороне сервера.

Краткий обзор технологий для Интернет-приложений

Настоящая статья адресована главным образом пользователям Интернета; ее цель — осветить некоторые современные Интернет-технологии с точки зрения их потребителя. Впрочем, как показывает практика, знание подобных вопросов необходимо и некоторым начинающим разработчикам.

10-15 лет назад большинство Web-сайтов представляло собой набор статических HTML-страниц. Сегодня подобные сайты по-прежнему встречаются — нередко именно так выполнены небольшие персональные Web-сайты, а также сайты небольших компаний, не претендующие ни на что, кроме размещения относительно небольшого объема редко меняющейся информации. Отметим, однако, что в процессе превращения Интернета из набора информационных ресурсов в инструмент ведения бизнеса технологии создания сайтов существенно изменились — большинство Web-сайтов крупных компаний представляет собой набор приложений, обладающих интерактивностью, средствами персонализации, средствами взаимодействия с клиентами (вплоть до приема заказов и платежей) и партнерами, а нередко — и средствами интеграции с «внутренними» корпоративными приложениями компании. О средствах создания подобных Web-сайтов чуть более подробно будет рассказано в статье «Продукты для создания корпоративных Интернет-решений» в настоящем номере журнала. В данной статье мы лишь кратко осветим технологии, лежащие в основе современных Web-приложений. Пользователь, имеющий дело с Web-приложениями (а в последнее время — и с Web-сервисами), общается с ними посредством Интернет-клиентов (чаще всего браузеров, но не только их — существуют и другие типы клиентских приложений, например чат-клиенты). Поэтому уместно отдельно поговорить о том, что может применяться в клиентских приложениях, а что — на Web-серверах.

Технологии, применяемые в Web-клиентах

дним из направлений развития Web-приложений стало размещение некоторой части логики приложения (такой как проверка корректности вводимых данных) в самом Web-клиенте, например в Web-браузере. В частности, современные Web-браузеры способны интерпретировать код на скриптовых языках, выполнять Java-апплеты и элементы управления ActiveX, использовать другие дополнения, такие как Macromedia Flash Player. Рассмотрим все эти возможности браузеров подробнее.

Скриптовые языки

Большинство современных Web-браузеров способно интерпретировать код на скриптовых языках, таких как VBScript и JavaScript. Код на этих языках внедряется в Web-страницу и интерпретируется браузером. Типичный пример применения скриптовых языков — проверка корректности данных, вводимых пользователем в соответствующие поля HTML-формы, непосредственно в процессе ввода или после него, без обращения к Web-серверу. Подобные примеры применения скриптовых языков можно обнаружить при заполнении некоторых анкет и получении сообщений о том, что не заполнены обязательные поля (справедливости ради отметим, что далеко не все анкеты реализованы подобным образом).

Однако есть и другие примеры применения скриптовых языков, реализующие как чисто дизайнерские идеи, например кнопки, меняющие свой вид при наведении на них курсора, «бегущие строки», так и иную функциональность, например внедренные в Web-страницы средства обращения к поисковым системам, отображение диалоговых панелей, управление другими объектами, встроенными в Web-страницу (например, Java-апплетами или элементами управления ActiveX, о которых будет рассказано ниже).

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

Java-апплеты

Практически все современные браузеры способны отображать и выполнять Java-апплеты — специальные Java-приложения, которые пользователь получает в составе Web-страницы. Эти приложения нередко включаются в состав Web-страниц с целью добавления функциональности, которую сложно или невозможно реализовать с помощью скриптовых языков. Апплеты могут выполняться на всех платформах, для которых доступна виртуальная Java-машина.

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

Илон Маск рекомендует:  Псевдокласс nth-child

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

Элементы управления ActiveX

Некоторые из современных браузеров (в частности, Microsoft Internet Explorer) могут служить контейнерами для элементов управления ActiveX — специальных COM-серверов, выполняющихся в адресном пространстве браузера и также получаемых в составе Web-страницы.

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

Естественно, Microsoft Internet Explorer обладает средствами ограничения возможностей выполнения элементов управления ActiveX, в том числе управления ими из кода на скриптовых языках. Однако для контроля безопасности их выполнения имеется еще одно средство, называемое электронной цифровой подписью. Цифровая подпись помещается внутрь элемента управления ActiveX, для чего требуется наличие соответствующего электронного сертификата. Электронная подпись, помимо сведений о фирме-производителе, содержит и другую полезную информацию. Так, например, если файл с элементом управления ActiveX после добавления электронной подписи был изменен, то об этом будет немедленно сообщено перед запуском такого элемента управления — при добавлении подписи к элементу управления ActiveX происходит вычисление контрольной суммы соответствующего файла. Отметим, однако, что в России в настоящее время нет авторизованных компаний, которые могли бы выдать электронный сертификат международного образца. Естественно, наличие электронного сертификата не гарантирует отсутствия потенциально опасного содержимого, но, по крайней мере, позволяет клиенту установить его источник.

Далее нам следует напомнить банальную истину, которая, как показывает практика, очевидна не для всех наших читателей. При работе с элементами управления ActiveX и Java-апплетами абсолютно бесполезно полагаться на антивирусное программное обеспечение (неважно, клиентское оно или серверное): признаков, характерных для вирусов (таких как способность внедряться внутрь исполняемых файлов и документов), подобные приложения, как правило, не содержат. Можно лишь запретить загрузку или выполнение соответствующего кода либо на уровне настроек браузера, либо на уровне корпоративных или персональных брандмауэров.

Приложения Macromedia Flash

Приложения Macromedia Flash являются сегодня наиболее популярным расширением функциональности Web-браузеров — с их помощью многие Web-дизайнеры придают своим сайтам интерактивность и оригинальность.

Модель безопасности приложений Flash основана на том, что Macromedia Flash Player, как и виртуальная Java-машина, выполняет приложения в ограниченном адресном пространстве, при этом выполняемые приложения не имеют доступа к файловой системе (кроме одного конкретного каталога, используемого Macromedia Flash Player для служебных целей) и другим ресурсам компьютера пользователя; исключение делается для микрофонов и видеокамер, однако пользователь должен дать разрешение на передачу данных, полученных с этих устройств. Доступ к сетевым ресурсам ограничивается доменом, с которого было получено приложение. Отметим, что приложения Flash также могут управляться с помощью кода JavaScript, присутствующего на той же странице. Сам Macromedia Flash Player для Microsoft Internet Explorer является элементом управления ActiveX и использует возможности элементов управления ActiveX для доступа к свойствам приложений Flash из скриптовых языков.


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

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

Технологии создания серверных частей Web-приложений

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

Common Gateway Interface (CGI) — это стандартный интерфейс, позволяющий выполнять серверные приложения, вызываемые через URL. Входной информацией для таких приложений служит содержимое HTTP-заголовка либо тело запроса, в зависимости от применяемого протокола. CGI-приложения генерируют HTML-код, который возвращается браузеру. Отметим, что в свое время широко использовался и термин «CGI-скрипт», происхождение которого объясняется тем, что подобные приложения писались на скриптовых языках типа Perl, выполняющихся, тем не менее, не в браузере, а на сервере. CGI-приложения можно создавать с помощью практически любого средства разработки, генерирующего консольные приложения для операционной системы, под управлением которой функционирует Web-сервер.

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

ISAPI и Apache DSO

Проблему ограниченной производительности Web-приложений, которые выполняются в отдельном адресном пространстве, можно решить, создав приложение в виде библиотеки, загружающейся в адресное пространство Web-сервера и при необходимости остающейся там для обработки последующих запросов от других клиентов; естественно, в этом случае Web-сервер должен поддерживать загрузку таких библиотек. Подобные приложения для Microsoft Internet Information Servise носят название ISAPI (Internet Server Application Program Interface), а для весьма популярного Web-сервера Apache такие библиотеки называются Apache DSO (Dynamic Shared Objects). Отметим, однако, что при создании как CGI-, так и ISAPI-приложений было довольно сложно отделить задачи Web-дизайна от задач, связанных с реализацией функциональности и логики приложений, — подобные приложения генерируют Web-страницы целиком, поэтому все данные, связанные с дизайном этих страниц, должны в общем случае содержаться внутри исполняемого файла.

ASP, JSP, PHP

Очередной шаг в развитии технологий создания Интернет-приложений — появление средств, позволяющих отделить задачи Web-дизайна от задач, связанных с реализацией функциональности приложений. Первой из таких технологий стала Active Server Pages (ASP), построенная на основе ISAPI-фильтра. Основная идея ASP заключается в создании Web-страниц с внедренными в них фрагментами кода на скриптовых языках. Однако, в отличие от рассмотренных выше средств применения скриптовых языков для расширения функциональности браузеров, указанные фрагменты кода интерпретируются не браузером, а сервером (точнее, предназначенной для этого ISAPI-библиотекой), и результат выполнения этих фрагментов кода замещает сам фрагмент кода в той версии страницы, которая передается в пользовательский браузер. Вскоре после ASP появились и другие технологии, реализующие идею размещения внутри Web-страницы кода, выполняемого Web-сервером. Наиболее известной из них сегодня является технология JSP (Java Server Pages), основная идея которой — однократная компиляция Java-кода (сервлета) при первом обращении к нему, выполнение методов этого сервлета и помещение результатов выполнения этих методов в набор данных, отправляемых в браузер. Еще одной популярной технологией подобного типа является PHP (Personal Home Pages), которая использует CGI-приложения, интерпретирующие внедренный в HTML-страницу код на скриптовом языке.

ASP .NET

Новейшей версией технологии Active Server Pages является ASP .NET, ключевая в архитектуре Microsoft .NET Framework. Основное отличие этой технологии от ASP с точки зрения архитектуры приложений заключается в том, что код, присутствующий на Web-странице, не интерпретируется, а компилируется и кэшируется, что, естественно, способствует повышению производительности приложений.

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

В общем случае клиентом Web-сервера может быть не только персональный компьютер, оснащенный обычными Web-клиентами (например, Web-браузером), но и мобильные устройства, отличающиеся ограниченным размером экрана, малым объемом памяти, а нередко и невозможностью отображения графики. Для этих устройств существуют свои протоколы передачи данных (Wireless Access Protocol, WAP) и соответствующие языки разметки (WML, Wireless MarkupLanguage, СHTML, Compact HTML и т.п.). При этом необходимо передавать данные на мобильное устройство в соответствующем формате, для чего нередко создаются специальные сайты (например, поддерживающие WAP и WML). Более удобным представляется создание приложений, которые способны генерировать тот или иной код в зависимости от типа клиента. Именно такой подход и реализован в Microsoft ASP .NET.

Несколько слов о серверах приложений

С ростом объема используемых данных и числа посетителей Web-сайтов возрастают требования к надежности, производительности и масштабируемости Web-приложений. Для удовлетворения этим требованиям бизнес-логика, реализованная в Web-приложении, а также сервисы обработки данных и реализации транзакций, отделяются от интерфейса приложений и переносятся на сервер приложений в виде бизнес-объектов. Серверы приложений и соответствующие бизнес-объекты могут быть различного типа (наиболее распространенными из них сегодня являются серверы, поддерживающие спецификацию Java2 Enterprise Edition, и серверы, базирующиеся на технологиях COM и Microsoft .NET). Впрочем, рассмотрение серверов приложений выходит за рамки данной статьи…

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

Web-сервисы

Говоря о серверных Web-технологиях, нельзя обойти вниманием такую важную, как Web-сервисы XML. На Web-сервисы XML в настоящее время нередко возлагается решение многих задач, связанных с интеграцией приложений, в том числе созданных на разных платформах. Создавать Web-сервисы можно и в виде исполняемых файлов, и в виде библиотек, и в виде интерпретируемого кода; существуют также средства представления бизнес-объектов в виде Web-сервисов. Методы Web-сервисов можно вызывать из обычных приложений, Web-приложений и других Web-сервисов, и, за редким исключением, конечные пользователи непосредственно с Web-сервисами дела не имеют. Тем не менее в последнее время отмечается массовое появление приложений, использующих Web-сервисы, в том числе и приложений, предназначенных для конечных пользователей.

Заключение

данной статье мы обсудили наиболее популярные технологии, применяемые при создании Web-приложений, а именно: средства расширения функциональности браузеров, такие как скриптовые языки, элементы управления ActiveX, Java-апплеты и приложения Macromedia Flash, а также технологии создания серверных Web-приложений, такие как CGI, ISAPI, ASP, JSP, PHP, ASP .NET.

Веб-приложения с использованием СУБД

После того как в предыдущей статье («Мир ПК», №12/06, с. 74) мы познакомились с концепцией создания приложений СУБД с использованием WAS CE и с понятием пула соединений, можно перейти к созданию простого приложения, взаимодействующего с БД.

Использование БД в серверных приложениях J2EE

Эта тема очень интересная и непростая, и о ней можно написать большую книгу. В данной статье мы, разумеется, не будем детально рассматривать эти вопросы, тем более что они не имеют отношения к конкретным реализациям J2EE-серверов, в частности к WAS CE. Однако понимание основных аспектов взаимодействия серверов приложений и серверов БД полезно в любом случае. Применительно к WAS CE польза будет состоять в том, что читателю станут гораздо более понятны странный на первый взгляд состав jar-файлов ../repository/ tranql/jars/tranql-1.2.2.jar и наличие нескольких rar-коннекторов в каталоге ../repository/tranql/ rars (и их общее назначение).

Локальные и глобальные транзакции

Само понятие транзакции хорошо знакомо программистам, работающим с БД (зачастую, правда, в весьма упрощенном варианте). А вот деление транзакций на локальные и глобальные появилось в связи с использованием распределенных многозвенных систем.

Локальными транзакциями при взаимодействии с базами данных называются транзакции, управление которыми берет на себя СУБД. С точки зрения программиста, использующего универсальный API для доступа к БД (например, JDBC), локальные транзакции создаются и завершаются в привязке к конкретному соединению с БД. В JDBC явное управление локальными транзакциями выполняется за счет вызова методов объекта типа Connection, таких как setAutoCommit(), commit() или rollback(). Этот режим работы характерен для написания приложений в архитектуре «клиент—сервер». СУБД использует однофазный режим завершения таких транзакций — другими словами, процедура завершения транзакции выполняется за одну команду (commit для подтверждения транзакции). При такой работе нет возможности создать транзакцию, которая «объединяла» бы действия — обычно операторы SQL — с использованием нескольких соединений.

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

Если же используется распределенная БД — другими словами, в контексте одной транзакции должны меняться данные сразу в нескольких БД, — то для решения этой задачи многие производители СУБД обеспечили возможность задания транзакции, выполняемой для нескольких БД этого типа. Такие операции можно условно назвать «локальными транзакциями с двухфазным завершением».

Возрастание требований к технологиям создания сложных проектов, их надежности и масштабируемости, а также возможность создания гетерогенных (разнотипных) распределенных БД привели к качественному изменению ситуации — появились технологии создания распределенных систем, наиболее развитыми и совершенными из которых являются CORBA, J2EE и .NET. Для распределенных систем понятие транзакции было распространено на информационную систему в целом, а не только на СУБД как часть такой системы. Транзакционной стала не только информация в долговременных хранилищах — таковыми стали объекты, из которых строится сама система. Вследствие этого встала задача совместной работы на уровне распределенных объектных транзакций и транзакций на уровне БД — хотя бы потому, что многие объекты хранят свое состояние в БД. Для управления распределенными объектными транзакциями в многозвенных системах существует специальная подсистема, которую обычно называют менеджером или координатором транзакций. В модели Distributed Transaction Process, разработанной консорциумом X/Open (сейчас входит в состав Open Group), появился специальный протокол взаимодействия между координатором транзакций и менеджером ресурсов. Задачей менеджера ресурсов является сохранение состояния транзакционных объектов распределенной системы в БД. Этот протокол получил название XA-протокола.

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

Поскольку протокол XA по определению является протоколом взаимодействия системных приложений — менеджера транзакций и менеджера ресурсов, то прикладному программисту нет необходимости знать детали этого протокола. Протокол XA — «внутренняя кухня» технологий создания распределенных систем, в том числе J2EE и JDBC.

Итак, глобальными называются транзакции, которые управляются внешним по отношению к СУБД координатором транзакций. Глобальные транзакции могут завершаться как в однофазном, так и в двухфазном режимах.

Транзакции и компонентная модель EJB

Компонентная модель EJB (Enterprise JavaBeans) предназначена для быстрого и качественного создания серверов приложений как основной части распределенных систем. Применительно к теме, затронутой в данной статье, нас будут интересовать два вида EJB-компонентов — session-компоненты с состоянием и entity-компоненты (чтобы окончательно не сбивать читателя с толку с помощью различной их трактовки в разных версиях EJB, будем понимать entity-компоненты в терминах EJB 2.x).

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

Другое дело, если он хочет сохранить состояние создаваемого объекта. Технология EJB не обеспечивает этого автоматически — об этом должен позаботиться сам программист. Обычно для упомянутой цели используется API JDBC, а именно: в коде компонента разработчик создает соединение с БД, начинает локальную транзакцию, задает нужные SQL-операторы, завершает транзакцию (или транзакции) и разрывает соединение.

На самом деле в таком режиме все только выглядит просто. Проблема состоит в том, что разработчик компонента сам не знает, в какой глобальной объектной транзакции участвует данный компонент, и команды управления локальными транзакциями, помещенные в его код, могут противоречить логике работы сервера приложения, который строится из многих составляющих, причем некоторые из них одновременно могут участвовать в одной и той же глобальной транзакции. Чтобы избежать такого рода конфликтов, среда исполнения EJB-компонентов либо запрещает применять команды управления локальными транзакциями в режиме использования транзакций глобальных, либо перехватывает такие команды и игнорирует их, а управление локальными транзакциями на уровне СУБД берет на себя менеджер глобальных транзакций. Другими словами, локальная транзакция на уровне объекта Connection API JDBC начинается и заканчивается не тогда, когда этого требуют правила JDBC или даже сам программист, а тогда, когда соответствующие команды даст глобальный координатор транзакций. Это очень облегчает жизнь прикладному программисту — обычно он просто не помещает в код session-компонентов с состоянием никаких команд управления транзакциями из состава JDBC API. Но за такие удобства для прикладного разработчика должны «расплачиваться» системные программисты — управление соединениями в распределенных системах самым тесным образом связано с управлением глобальными транзакциями.

Еще интереснее обстоит дело с entity-компонентами.

Entity-компоненты по определению являются кэшированным объектным представлением данных из БД на уровне сервера приложения и управляются командами менеджера глобальных транзакций. Несколько упрощая, можно сказать так: при начале глобальной объектной транзакции для данного конкретного компонента его состояние синхронизируется с состоянием БД путем чтения информации из нее (SQL-команда SELECT), при завершении глобальной транзакции измененное в процессе транзакции состояние компонента записывается в БД (SQL-команда UPDATE).

Особенностью entity-компонентов в модели EJB является автоматизация управления состоянием компонента. Программист, создавая компонент, работает с логическими сущностями — как на уровне Java-кода самого компонента, так и на уровне БД. Эта совокупность логических представлений называется «абстрактной схемой» компонента. Для удобства работы с компонентами при таком подходе автору компонента нельзя использовать конкретные названия физических полей в реальной базе данных хотя бы потому, что автор компонента этих названий может просто не знать. То есть использовать при создании компонента язык SQL нельзя. Для тех случаев, когда без него обойтись невозможно, в EJB создан специальный язык, похожий на упрощенный SQL, — Query Language (QL). Операторы QL должны быть переведены в соответствующие SQL-операторы либо на стадии развертывания компонента, либо динамически, в процессе работы. Все это опять-таки увязывает между собой такие разные фрагменты технологий, как управление соединениями, транзакциями, поддержку QL, особенности объектно-реляционного отображения entity-компонентов и многое другое.

После такого общего обзора можно вернуться с небес на землю и создать простое веб-приложение, «общающееся» с БД.

Создание БД и подготовка ее к использованию

В общем случае при использовании WAS CE/Geronimo процесс создания и подготовки БД к работе состоит из следующих шагов:

  • запуск (или поиск в сети) нужного сервера БД;
  • создание на нем экземпляра БД как логической совокупности таблиц, индексов, представлений, триггеров, хранимых процедур и проч. Для этой цели используются инструменты, поставляемые самим разработчиком СУБД;
  • создание пула соединений с этой БД с нужными свойствами и в нужном режиме. Подробно об этом говорилось в предыдущей статье.

В состав WAS CE в качестве одного из сервисов входит СУБД Derby — реализация реляционной БД с открытым исходным текстом. Эта СУБД используется многими сервисами и компонентами WAS CE для решения системных задач, но прикладной программист — особенно для учебных задач — может использовать ее как рабочую СУБД для хранения необходимых данных.

Поскольку СУБД Derby интегрирована в состав WAS CE, использовать ее проще, чем другие СУБД, — в частности, за счет того, что в состав консоли администратора WAS CE входит менеджер управления БД Derby.

В нашем простейшем примере в состав БД (уже существующая БД SystemDatabase) будет входить только одна таблица. Оператор SQL для ее создания имеет такой вид:

Выполнить эту команду можно, набрав ее в поле текста команды менеджера Derby (рис. 1) при выбранной нужной БД (SystemDatabase в данном примере).

Рис. 1. Менеджер СУБД Derby

Нужные данные можно внести в таблицу с помощью одного или нескольких SQL-операторов INSERT. Для просмотра содержимого таблиц Derby можно задать SQL-оператор SELECT или воспользоваться средствами просмотра содержимого, предоставляемыми менеджером БД Derby.

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

Что касается предустановленной БД с именем SystemDatabase, то для нее уже создан пул соединений с именем SystemDatasource и списком свойств, отраженным на рис. 2.

Рис. 2. Свойства пула соединений для БД SystemDatabase

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

Использование параметров пула соединений в дескрипторах J2EE-модулей

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

  • Важнейшим элементом приложения, использующего БД, является установление связи между пулом и приложением.
  • Программист работает с высокоуровневой моделью взаимодействия с СУБД: он получает (обычно с помощью JNDI) доступ к фабрике соединений, роль которой в JDBC играет интерфейс DataSource и производные от него интерфейсы, а затем с помощью вызова метода getConnection() устанавливает логическое соединение с сервером.
  • Спецификация J2EE требует, чтобы настройкой занимался не программист, а специалист, реализующий J2EE-роль под названием deployer. Он работает с xml-дескрипторами модулей, из которых строится J2EE-приложение.
  • Обычно обращения к пулам соединений с БД выполняются из модулей, которые содержат веб- или EJB-компоненты. Пул соединений трактуется как ресурс J2EE, что приводит к использованию тега в стандартных xml-дескрипторах.
  • Специфика реализации практически любого J2EE-сервера требует использования не только стандартного, но и дополнительного xml-дескриптора.

С текстами xml-дескрипторов мы уже знакомы. Основной дескриптор имеет имя web.xml и может содержать следующие строки:

План развертывания WAS CE (специфический для WAS CE дескриптор) имеет имя geronimo-web.xml и может выглядеть так:

Несмотря на то что в большинстве случаев удобнее всего использовать стандартный подход, при котором файлы дескрипторов имеют предопределенные имена (web.xml и geronimo-web.xml) и находятся в каталоге WEB-INF архива веб-приложения (WAR-файла), возможны альтернативные решения, которые зависят от формата создаваемого приложения.

Простые веб-приложения, подобные рассматриваемому в данном примере, можно создавать, а затем развертывать на сервере в виде отдельного WAR-файла. В этом случае специфический для WAS CE xml-дескриптор можно назвать любым именем и хранить его в произвольном месте, не включая в состав war-архива, а при развертывании приложения на сервере просто указать это имя в командной строке, например:

Использование пула на уровне Java-кода

Для простоты приложение будем создавать в виде JSP-документа (пусть он имеет имя my_derby_app.jsp). б?ольшую часть этого документа будет занимать Java-код, HTML-теги понадобятся только для форматирования выводимых данных. Текст вряд ли нуждается в дополнительных пояснениях:

После того как будет создан WAR-файл приложения (который содержит три файла — xml-дескрипторы в подкаталоге WEB-INF и JSP-документ в корневом каталоге), созданное веб-приложение нужно развернуть на сервере с помощью команды deploy.

Для просмотра записей в таблице при работе с браузером нужно задать следующий URL: http://localhost:8080/derby_webdb/my_derby_app.jsp.

WAS CE предоставляет разработчикам все необходимое для создания приложений БД, доступ к которым осуществляется с помощью использования интернет-браузера на рабочем месте клиента.

Подходы к архитектурному проектированию веб-приложений

Рубрика: Информационные технологии

Дата публикации: 05.03.2020 2020-03-05

Статья просмотрена: 1790 раз

Библиографическое описание:

Богданенко Д. А. Подходы к архитектурному проектированию веб-приложений // Молодой ученый. — 2020. — №9. — С. 24-29. — URL https://moluch.ru/archive/195/48609/ (дата обращения: 12.11.2020).

Ключевые слова: веб, приложение, архитектура, веб-приложение.

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

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

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

  1. Монолитный подход
  2. Модульный подход
  3. SOA[1] или Сервис-ориентированный подход

Монолитный подход является самой старой моделью проектирования ПО поскольку именно с неё и началась разработка всего программного обеспечения. В рамках данного подхода сложной структуры веб-приложения как таковой может не быть: сервер хранит всю бизнес-логику, а база данных — данные необходимые серверу для работы.

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

Проблемы с поддержкой монолитного приложения можно объяснить и тем, что рано или поздно небольшой список функционала в системе пополняется новыми требованиями и идеями, которые требую внесения изменений в уже существующий код, что уже отражается в последнем предложении предыдущего абзаца. Кроме того, в рамках веб-приложения одной из проблем «монолита» является масштабируемость. Все составляющие системы расположены в одной точке, а потому мощность самой точки должна быть соответствующей для поддержки сервера и базы данных в рабочем состоянии.

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

Рис. 1. Структура обычного веб-приложения

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

Далее приведён пример кода простого приложения с монолитной архитектурой, который располагается на сервере, который выводит ту или иную страницу в зависимости от пришедшего на сервер запроса.

Данное приложение написано на языке PHP. Входной точкой в приложение служит файл index.php, который и обрабатывает все входящие запросы. При входе в веб-приложение PHP включает метод get_server_params из одноимённого файла, который расположен в папке utils и в последствии использует его для получения значения содержавшегося в свойстве “REQUEST_URI” пришедших вместе с запросом на сервер.

Приведённое приложение является чисто показательным. В действительности, приложения даже в случае монолитной архитектуры будут выглядеть более структурированно и слаженно, а также иметь более продуманную систему маршрутов, в данной статье за это отвечает обычный switchcase. Разработать подобное приложение может каждый, но поддерживать его долго и включать в него всё новый функционал с определённого момент времени будет сложнее, если только не прибегнуть к рефакторингу[2] приложения, однако наступление этого момента отчасти зависит от профессионализма разработчика.

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

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

Стоит отметить, что при изменении одного модуля, другие модули затронуты не будут, а потому упрощается задача debug’а[3]. Всё, что потребуется, это подстроить остальные модули, использующие функционал изменённого модуля под новые возможности и требования последнего, если изменения в нём могут привести к сбою в работе приложения.

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

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

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

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

Рис. 2. Модульное приложения состоящее из клиентской (Frontend) и серверной (Backend) части

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

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

По факту не является критичным что конкретно используется на клиентской и серверной части. Клиентом может быть и Vue.js, и Angular, и «чистый» JS, а серверная часть может быть написана на Java, NET, C#, C++ и других языках.

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

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

Возможность разработки целостного приложения сервис-ориентированным подходом, предоставляет возможность разработки сервисов на разных языках программирования. Простой пример: сервис доставки сообщений может быть написан на NodeJS, где языком программирования используется JavaScript, в то время как основное приложение, использующее этот сервис, может состоять из связки React на клиентской части и PHP на серверной части. Для взаимодействия этих двух частей необходимо только правильно использовать программный интерфейс сервиса в основной части приложения.

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

Рис. 3. Сервис-ориентированная архитектура приложения

На рисунке выше изображена топология сети сервис-ориентированного веб-приложения типа «кольцо». В рамках данного приложения пользователь всегда попадает на сервер приложения с IP-адресом 192.168.0.30 и предоставляет общий интерфейс для работы с пользователем. Предположим, что веб-приложение отправляет почту и уведомления, а соответственно либо этот функционал нужно реализовать на сервере приложений, что является модульным подходом, либо выделить ему отдельный сервер в качестве отдельного сервиса, что и изображено на картинке выше.

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

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

Илон Маск рекомендует:  Использование компонента tcoolbar или как создавать кульные панели инструментов

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

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

«Чем больше сила, тем больше ответственность». Данное выражение отлично подходит к сервис-ориентированным приложения, поскольку данный архитектурный подход не прощает ошибок и любой недочёт может серьёзным образом сказаться на всей работоспособности системы.

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

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

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

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

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

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

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

  1. Микросервисы или монолит: в поисках золотой середины // Корпоративный блог компании Грамант. URL: http://blog.gramant.ru/2020/05/17/microservices-vs-monolith-compromise/ (дата обращения: 1.03.2020).
  2. Когда использовать монолиты, а когда микросервисы // Записки программиста. URL: https://eax.me/microservices-vs-monolithic/ (дата обращения: 1.03.2020).

[1] Service Oriented Architecture (англ.) – Сервис-ориентированная архитектура

[2] Процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы (https://ru.wikipedia.org/wiki/Рефакторинг)

[3] Debug – (англ.) – отладка, обычно подразумевает отладку приложения в случае ошибок или запуск приложения в режиме который позволяет отловить различного рода ошибки

Грамотная клиент-серверная архитектура: как правильно проектировать и разрабатывать web API

Рассказывает Владимир, веб-разработчик Noveo

Большинству разработчиков сайтов, веб-сервисов и мобильных приложений рано или поздно приходится иметь дело с клиент-серверной архитектурой, а именно разрабатывать web API или интегрироваться с ним. Чтобы не изобретать каждый раз что-то новое, важно выработать относительно универсальный подход к проектированию web API, основываясь на опыте разработки подобных систем. Предлагаем вашему вниманию объединенный цикл статей, посвящённых этому вопросу.

Приближение первое: Действующие лица

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

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

Клиент и сервер

Сервером в данном случае мы считаем абстрактную машину в сети, способную получить HTTP-запрос, обработать его и вернуть корректный ответ. В контексте данной статьи совершенно не важны его физическая суть и внутренняя архитектура, будь то студенческий ноутбук или огромный кластер из промышленных серверов, разбросанных по всему миру. Нам в той же мере совершенно неважно, что у него под капотом, кто встречает запрос у дверей, Apache или Nginx, какой неведомый зверь, PHP, Python или Ruby выполняет его обработку и формирует ответ, какое хранилище данных используется: Postgresql, MySQL или MongoDB. Главное, чтобы сервер отвечал главному правилу — услышать, понять и простить ответить.

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

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

Философия REST

REST (Representational state transfer) изначально был задуман как простой и однозначный интерфейс для управления данными, предполагавший всего несколько базовых операций с непосредственным сетевым хранилищем (сервером): извлечение данных (GET), сохранение (POST), изменение (PUT/PATCH) и удаление (DELETE). Разумеется, этот перечень всегда сопровождался такими опциями, как обработка ошибок в запросе (корректно ли составлен запрос), разграничение доступа к данным (вдруг этого вам знать не следует) и валидация входящих данных (вдруг вы написали ерунду), в общем, всеми возможными проверками, которые сервер выполняет перед тем, как выполнить желание клиента.

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

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

Пример: GET /api/v1/users/25/name

Независимость формата хранения данных от формата их передачи — сервер может поддерживать несколько различных форматов для передачи одних и тех же данных (JSON, XML и т.д.), но хранит данные в своем внутреннем формате, независимо от поддерживаемых.

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

Чего нам не хватает


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

Вызовы функций

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

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

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

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

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

Множественные операции

Часто бывает так, и разработчики клиентов поймут, о чем я, что клиентскому приложению удобнее создавать/изменять/удалять/ сразу несколько однородных объектов одним запросом, и по каждому объекту возможен свой вердикт серверной стороны. Тут есть как минимум несколько вариантов: либо все изменения выполнены, либо они выполнены частично (для части объектов), либо произошла ошибка. Ну и стратегий тоже несколько: применять изменения только в случае успеха для всех, либо применять частично, либо откатываться в случае любой ошибки, а это уже тянет на полноценный механизм транзакций.

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

Статистические запросы, агрегаторы, форматирование данных

Частенько бывает так, что на основе хранимых на сервере данных нам нужно получить статистическую выжимку или данные, отформатированные особым образом: например, для построения графика на стороне клиента. По сути это данные, генерируемые по требованию, в той или иной мере на лету, и доступные только для чтения, так что имеет смысл вынести их в отдельную категорию. Одной из отличительных особенностей статистических данных, на мой взгляд, является то, что они не имеют уникального ID.

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

Разновидности данных

Объекты

Ключевым типом данных в общении между клиентом и сервером выступает объект. По сути, объект – это перечень свойств и соответствующих им значений. Мы можем отправить объект на сервер в запросе и получить в результат запроса в виде объекта. При этом объект не обязательно будет реальной сущностью, хранящейся в базе данных, по крайней мере, в том виде, в котором он отправлен или получен. Например, учетные данные для авторизации передаются в виде объекта, но не являются самостоятельной сущностью. Даже хранимые в БД объекты склонны обрастать дополнительными свойствами внутрисистемного характера, например, датами создания и редактирования, различными системными метками и флагами. Свойства объектов могут быть как собственными скалярными значениями, так и содержать связанные объекты и коллекции объектов, которые не являются частью объекта. Часть свойств объектов может быть редактируемой, часть системной, доступной только для чтения, а часть может носить статистический характер и вычисляться на лету (например, количество лайков). Некоторые свойства объекта могут быть скрыты, в зависимости от прав пользователя.

Коллекции объектов

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

Скалярные значения

В чистом виде скалярные значения как отдельная сущность на моей памяти встречались крайне редко. Обычно они фигурировали как свойства объектов или коллекций, и в этом качестве они могут быть доступны как для чтения, так и для записи. Например, имя пользователя может быть получено и изменено в индивидуальном порядке GET /users/1/name . На практике эта возможность пригождается редко, но в случае необходимости хотелось бы, чтобы она была под рукой. Особенно это касается свойств коллекции, например числа записей (с фильтрацией или без нее): GET /news/count .

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

Приближение второе: Правильный путь

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

О чем стоит подумать, стоя на берегу

Версионность

Рано или поздно любая действующая система начинает эволюционировать: развиваться, усложняться, масштабироваться, усовремениваться. Для разработчиков REST API это чревато в первую очередь тем, что необходимо запускать новые версии API при работающих старых. Здесь я говорю больше не об архитектурных изменениях под капотом вашей системы, а о том, что изменяется сам формат данных и набор операций с ними. В любом случае версионность нужно предусмотреть как в изначальной организации исходного кода, так и в принципе построения URL. Что касается URL, здесь существует два наиболее популярных способа указания версии API, которой адресован запрос. Префиксация пути example-api.com/v1/ и разведение версий на уровне субдомена v1.example-api.com . Использовать можно любой из них, в зависимости от потребности и необходимости.

Автономность компонентов

Web API сложных систем, поддерживающих несколько пользовательских ролей, зачастую требует разделения на части, каждая из которых обслуживает свой спектр задач. По сути, каждая часть может быть самостоятельным приложением, работать на разных физических машинах и платформах. В контексте описания API нам совершенно не важно, как сервер обрабатывает запрос и какие силы и технологии в этом замешаны. Для клиента API – система инкапсулированная. Тем не менее разные части системы могут обладать совершенно разной функциональностью, например, административная и пользовательская часть. И методология работы с одними и теми же, казалось бы, ресурсами может существенно отличаться. Поэтому такие части необходимо разделять на уровне домена admin.v1.example-api.com или префикса пути example-api.com/v1/admin/ . Это требование не является обязательным, и многое зависит от сложности системы и её назначения.

Формат обмена данными

Самым удобным и функциональным, на мой взгляд, форматом обмена данными является JSON, но никто не запрещает использовать XML, YAML или любой другой формат, позволяющий хранить сериализованные объекты без потери типа данных. При желании можно сделать в API поддержку нескольких форматов ввода/вывода. Достаточно задействовать HTTP заголовок запроса для указания желаемого формата ответа Accept и Content-Type для указания формата переданных в запросе данных. Другим популярным способом является добавление расширения к URL ресурса, например, GET /users.xml , но такой способ кажется менее гибким и красивым, хотя бы потому, что утяжеляет URL и верен скорее для GET-запросов, нежели для всех возможных операций.

Локализация и многоязычность

На практике многоязычность API чаще всего сводится к переводу сервисных сообщений и сообщений об ошибках на требуемый язык для прямого отображения конечному пользователю. Многоязычный контент тоже имеет место быть, но сохранение и выдача контента на разных языках, на мой взгляд, должна разграничиваться более явно, например, если у вас одна и та же статья существует на разных языках, то по факту это две разных сущности, сгруппированные по признаку единства содержания. Для идентификации ожидаемого языка можно использовать разные способы. Самым простым можно считать стандартный HTTP-заголовок Accept-Language . Я встречал и другие способы, такие, как добавление GET-параметра language=»en» , использование префикса пути example-api.com/en/ или даже на уровне доменного имени en.example-api.com . Мне кажется, что выбор способа указания локали зависит от конкретного приложения и задач, стоящих перед ним.

Внутренняя маршрутизация

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

Пути к коллекциям

Для указания пути к коллекции мы просто используем название соответствующей сущности, например, если это список пользователей, то путь будет таким /users . К коллекции как таковой применимы два метода: GET (получение лимитированного списка сущностей) и POST (создание нового элемента). В запросах на получение списков мы можем использовать множество дополнительных GET параметров, применяемых для постраничного вывода, сортировки, фильтрации, поиска etc, но они должны быть опциональными, т.е. эти параметры не должны передаваться как часть пути!

Элементы коллекции

Для обращения к конкретному элементу коллекции мы используем в маршруте его уникальный идентификатор /users/25 . Это и есть уникальный путь к нему. Для работы с объектом применимы методы GET (получение объекта), PUT/PATCH (изменение) и DELETE (удаление).

Уникальные объекты

Во множестве сервисов существуют уникальные для текущего пользователя объекты, например профиль текущего пользователя /profile , или персональные настройки /settings . Разумеется, с одной стороны, это элементы одной из коллекций, но они являются отправной точкой в использовании нашего Web API клиентским приложением, и к тому же позволяют намного более широкий спектр операций над данными. При этом коллекция, хранящая пользовательские настройки может быть вообще недоступна из соображений безопасности и конфиденциальности данных.

Свойства объектов и коллекций

Для того, чтобы добраться до любого из свойств объекта напрямую, достаточно добавить к пути до объекта имя свойства, например получить имя пользователя /users/25/name . К свойству применимы методы GET (получение значения) и PUT/PATCH (изменение значения). Метод DELETE не применим, т.к. свойство является структурной частью объекта, как формализованной единицы данных.

В предыдущей части мы говорили о том, что у коллекций, как и у объектов, могут быть собственные свойства. На моей памяти мне пригодилось только свойство count, но ваше приложение может быть более сложным и специфичным. Пути к свойствам коллекций строятся по тому же принципу, что и к свойствам их элементов: /users/count . Для свойств коллекций применим только метод GET (получение свойства), т.к. коллекция – это только интерфейс для доступа к списку.

Коллекции связанных объектов

Одной из разновидностей свойств объектов могут быть связанные объекты или коллекции связанных объектов. Такие сущности, как правило, не являются собственным свойством объекта, а лишь отсылками к его связям с другими сущностями. Например, перечень ролей, которые были присвоены пользователю /users/25/roles . По поводу работы с вложенными объектами и коллекциями мы подробно поговорим в одной из следующих частей, а на данном этапе нам достаточно того, что мы имеем возможность обращаться к ним напрямую, как к любому другому свойству объекта.

Функции объектов и коллекций

Для построения пути к интерфейсу вызова функции у коллекции или объекта мы используем тот же самый подход, что и для обращения к свойству. Например, для объекта /users/25/sendPasswordReminder или коллекции /users/disableUnconfirmed . Для вызовов функций мы в любом случае используем метод POST. Почему? Напомню, что в классическом REST не существует специального глагола для вызова функций, а потому нам придется использовать один из существующих. На мой взгляд, для этого больше всего подходит метод POST т.к. он позволяет передавать на сервер необходимые аргументы, не является идемпотентным (возвращающим один и тот же результат при многократном обращении) и наиболее абстрактен по семантике.

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

Приближение третье: Запросы и ответы

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

Универсальный ответ

Мы уже проговаривали, что конкретный формат общения сервера с клиентом может быть любым на усмотрение разработчика. Для меня наиболее удобным и наглядным кажется формат JSON, хотя в реальном приложении может быть реализована поддержка нескольких форматов. Сейчас же сосредоточимся на структуре и необходимых атрибутах объекта ответа. Да, все данные, возвращаемые сервером, мы будем оборачивать в специальный контейнер — универсальный объект ответа, который будет содержать всю необходимую сервисную информацию для его дальнейшей обработки. Итак, что это за информация:

Success — маркер успешности выполнения запроса

Для того, чтобы при получении ответа от сервера сразу понять, увенчался ли запрос успехом, и передать его соответствующему обработчику, достаточно использовать маркер успешности «success». Самый простой ответ сервера, не содержащий никаких данных, будет выглядеть так:

Error — сведения об ошибке

В случае, если выполнение запроса завершилось неудачей — о причинах и разновидностях отрицательных ответов сервера поговорим чуть позже, — к ответу добавляется атрибут «error», содержащий в себе HTTP-код статуса и текст сообщения об ошибке. Прошу не путать с сообщениями об ошибках валидации данных для конкретных полей. Правильнее всего, на мой взгляд, возвращать код статуса и в заголовке ответа, но я встречал и другой подход — в заголовке всегда возвращать статус 200 (успех), а детали и возможные данные об ошибках передавать в теле ответа.

Data — данные, возвращаемые сервером

Большинство ответов сервера призваны возвращать данные. В зависимости от типа запроса и его успеха ожидаемый набор данных будет разным, тем не менее атрибут«data» будет присутствовать в подавляющем большинстве ответов.

Пример возвращаемых данных в случае успеха. В данном случае ответ содержит запрашиваемый объект user.

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

Pagination — сведения, необходимые для организации постраничной навигации

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

Минимальный набор значений для пагинации состоит из:

  • общего числа записей;
  • числа страниц;
  • номера текущей страницы;
  • числа записей на странице;
  • максимального числа записей на странице, поддерживаемого серверной стороной.

Некоторые разработчики web API также включают в пагинацию набор готовых ссылок на соседние страницы, а также первую, последнюю и текущую.

Работа над ошибками

Как уже упоминалось выше, не все запросы к web API завершаются успехом, но это тоже часть игры. Система информирования об ошибках является мощным инструментом, облегчающим работу клиента и направляющим клиентское приложение по правильному пути. Слово «ошибка» в этом контексте не совсем уместно. Здесь больше подойдёт слово исключение, так как на самом деле запрос успешно получен, проанализирован, и на него возвращается адекватный ответ, объясняющий, почему запрос не может быть выполнен.

Каковы же потенциальные причины получаемых исключений?

500 Internal server error — всё сломалось, но мы скоро починим

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

400 Bad request — а теперь у вас всё сломалось

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

401 Unauthorized — незнакомец, назови себя

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

403 Forbidden — вам сюда нельзя

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

404 Not found — по этому адресу никто не живёт

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

405 Method not allowed — нельзя такое делать

Эта разновидность исключения напрямую связана с использованным при запросе глаголом (GET, PUT, POST, DELETE), который, в свою очередь, свидетельствует о действии, которое мы пытаемся совершить с ресурсом. Если запрошенный ресурс не поддерживает указанное действие, сервер говорит об этом прямо.

422 Unprocessable entity — исправьте и пришлите снова

Одно из самых полезных исключений. Возвращается каждый раз, когда в данных запроса существуют логические ошибки. Под данными запроса мы подразумеваем либо набор параметров и соответствующих им значений, переданных методом GET, либо поля объекта, передаваемого в теле запроса методами POST, PUT и DELETE. Если данные не прошли валидацию, сервер в секции «data» возвращает отчет о том, какие именно параметры невалидны и почему.

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

Запросы

Получение элементов коллекции

Одним из наиболее частотных запросов является запрос на получение элементов коллекции. Информационные ленты, списки товаров, различные информационные и статистические таблицы и многое другое клиентское приложение отображает посредством обращения к коллекционным ресурсам. Для осуществления этого запроса мы обращаемся к коллекции, используя метод GET и передавая в строке запроса дополнительные параметры. Как мы уже обозначили выше, в качестве ответа мы ожидаем получить массив однородных элементов коллекции и информацию, необходимую для пагинации — подгрузки продолжения списка или же конкретной его страницы. Содержимое выборки может быть особым способом ограничено и отсортировано с помощью передачи дополнительных параметров. О них и пойдёт речь далее.

Постраничная навигация

page — параметр указывает на то, какая страница должна быть отображена. Если этот параметр не передан, то отображается первая страница. Из первого же успешного ответа сервера будет ясно, сколько страниц имеет коллекция при текущих параметрах фильтрации. Если значение превышает максимальное число страниц, то разумнее всего вернуть ошибку 404 Not found.

perPage — указывает на желаемое число элементов на странице. Как правило, API имеет собственное значение по умолчанию, которое возвращает в качестве поля perPage в секции pagination, но в ряде случаев позволяет увеличивать это значение до разумных пределов, предоставив максимальное значение maxPerPage:

Сортировка результатов

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

sortBy — существует несколько подходов к передаче данных о сложной сортировке в GET параметрах. Здесь необходимо четко указать порядок сортировки и направление.

В некоторых API это предлагается сделать в виде строки:

В других вариантах предлагается использовать массив:

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

Простая фильтрация по значению

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

Усложнённые варианты фильтрации

Многие интерфейсы требуют более сложной системы фильтрации и поиска. Перечислю основные и наиболее часто встречаемые варианты фильтрации.

Фильтрация по верхней и нижней границе с использованием операторов сравнения from (больше или равно), higher (больше), to (меньше или равно), lower (меньше). Применяется к полям, значения которых поддаются ранжированию.

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

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

Именованные фильтры

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

Именованные фильтры могут также иметь свои параметры.

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

За перевод материала выражаем благодарность международной IT-компании Noveo.

Проектирование приложения

Проектирование целевого приложения предполагало собой несколько этапов, которые в последствии должны работать как единое целое:

  • 1) Спроектировать и создать веб-интерфейс для настройки приложения — ввода страницы или условий поиска на сайте магазина, названия полей (селекторы) для анализа.
  • 2) Реализовать веб-сервис и веб-страницу для программного и ручного доступа к системе (просмотр статистики).
  • 3) Спроектировать и создать базу данных для приложения.
  • 4) Реализовать алгоритм парсинга html с помощью библиотеки CSQuery.
  • 5) Реализовать механизм выполнения серверных задач по расписанию и отправки уведомлений пользователю.

В ходе создания приложения первый и второй пункт были объеденены, так как использую asp.net web form они были успешно созданы в рамках одного веб-сайта. Также в ходе создания приложения было решено использовать одну базу данных и для хранения параметров, введенных пользователем (пункт 1) и для хранения результатов мониторинга и последующего доступа к его результатам (пункт 2).

Создание интерфейса

Известно два основных метода создания собственного активного сервера Web с использованием базы Micrоsoft Internet Infоrmation Server:

  • 1. С применением программ расширения CGI (или ISAPI)
  • 2. С помощью активных серверных страниц ASP.

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

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

Что же касается второго способа (с помощью активных серверных страниц ASP), то он значительно проще, несмотря на то, что позволяет решать те же самые задачи, что и программные расширения сервера Web. Страницы ASP представляют собой текстовые файлы с конструкциями языка HTML, классами и сценариями, составленными на таких языках программирования, как JScript и VB Script. Поэтому при условии хороших знаний таких языков программирования как (VB script) написание веб-приложения с использованием технологии ASP не составит труда.

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

  • 1. Регистрация с последующим занесением (e-mail и пароля в базу данных).
  • 2. Введение параметров мониторинга
  • 3. Выбор периода мониторинга
  • 4. Доступ к собранной информации.
Илон Маск рекомендует:  Сериализация объектов объекты в сессиях

Сам пользовательский интерфейс представляет из себя веб-форму, на которой представлены следующая информация:

  • -главная страница с основной информацией о приложении и необходимыми ссылками на более подробное описание аспектов программы.
  • -панель быстрого доступа расположенная сверху:
  • *МИЭМ НИУ ВШЭ — ссылка на главную страницу университета
  • *Главная — переход на домашнюю страницу
  • *Информация — более подробные сведения о веб-приложении
  • *Связаться — мои контакты
  • *Начать работу — пользовательский интерфейс позволяющий создать, изменить или удалить задачу
  • *Мой мониторинг — позволяет получить подробную информацию о каждом мониторинге, но не предоставляет возможность приостановить мониторинг.

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

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

Доступ к основному функционалу приложения возможен только после регистрации пользователя. А именно к вкладкам «начать работу» и мой мониторинг».

Весь пользовательский интерфейс был реализован с помощью ASP.net Web-forms.

Рис. 1 Демонстрация веб-сайта, созданного с помощью web-forms

Модель ASP.NET Web Forms изначально проектировалась для того, чтобы реализовать потенциал RAD в среде Web. Таким образом, главным определяющим фактором для большинства основных характеристик и ключевых концепций ASP.NET было стремление к производительности программирования. Модель Web Forms базируется на трех основных концепциях: обратной передаче страниц, состоянии просмотра и серверных элементах управления. Эти три концепции работают совместно в соответствии с моделью, изображенной на рис. 1. Каждый запрос HTTP, передаваемый веб-серверу и сопоставляемый со средой выполнения ASP.NET, проходит несколько стадий, в которых центральное место занимает обработка события обратной передачи (postback). Событие обратной передачи — главное действие, которое ожидает получить пользователь в результате обработки своего запроса.

Рис. 2 модель Web-Forms

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

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

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 28.08.2020
Размер файла 614,4 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

Размещено на http://www.allbest.ru/

1. Постановка задачи

2. Проектирование приложения

3. Создание интерфейса

4. Реализация логики приложения


5. Windows Task Sheduler

6. Использованные ресурсы, технологии и подходы

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

Основные плюсы построения веб-приложений для поддержки стандартных функций браузера состоят в том, что работа программы должна поддерживаться независимо от операционной системы любого клиента (вышеупомянутая кроссплатформенность). Таким образом, вместо того, чтобы писать различные версии одного и того же приложения для Windows, MacOS, Linux и других операционных систем, приложение создаётся один раз для любой платформы и на ней использую функции браузера поддерживается работоспособность. Однако при создании веб-приложений и их последующей поддержке различные варианты реализации языков разметки и других спецификаций в браузерах может вызвать проблемы. Помимо этого, возможность юзера настраивать многие параметры браузера, как то, например: размер шрифта, цвета, переход на мобильную версию — может препятствовать корректной работе приложения. Но использование активных серверных страниц ASP позволило в большей степени избежать данных проблем.

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

Для реализации поставленной задачи были выбраны активные серверные страницы ASP. Вся работа была выполнена с помощью Visual Studio 2015. Для написания сценариев использовался C#. Работа с базами данных осуществлялась с помощью поставщика БД SQL server.

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

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

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

То есть веб-приложение, созданное в ходе выполнения дипломной работы должна предоставлять пользователю следующие возможности:

1. Дружественный веб-интерфейс с основной информацией и необходимыми данными для успешного запуска данного приложения.

2. Обеспечить успешный парсинг html кода необходимой веб-страницы и поиск цен.

3. Занесение в базу данных информации введенной пользователем: Имя, персональный id, ссылка на товар, селектор и период мониторинга.

4. Занесение в базу данных, структурировании информации из логов парсинга.

5. Предоставление пользователю возможности добавлять, удалить и исправлять внесенные им данные.

6. Предоставление пользователю упрощенного доступа к данным содержащимся в БД мониторинга.

Проектирование целевого приложения предполагало собой несколько этапов, которые в последствии должны работать как единое целое:

1) Спроектировать и создать веб-интерфейс для настройки приложения — ввода страницы или условий поиска на сайте магазина, названия полей (селекторы) для анализа.

2) Реализовать веб-сервис и веб-страницу для программного и ручного доступа к системе (просмотр статистики).

3) Спроектировать и создать базу данных для приложения.

4) Реализовать алгоритм парсинга html с помощью библиотеки CSQuery.

5) Реализовать механизм выполнения серверных задач по расписанию и отправки уведомлений пользователю.

В ходе создания приложения первый и второй пункт были объеденены, так как использую asp.net web form они были успешно созданы в рамках одного веб-сайта. Также в ходе создания приложения было решено использовать одну базу данных и для хранения параметров, введенных пользователем (пункт 1) и для хранения результатов мониторинга и последующего доступа к его результатам (пункт 2).

Известно два основных метода создания собственного активного сервера Web с использованием базы Micrоsoft Internet Infоrmation Server:

1. С применением программ расширения CGI (или ISAPI)

2. С помощью активных серверных страниц ASP.

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

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

Что же касается второго способа (с помощью активных серверных страниц ASP), то он значительно проще, несмотря на то, что позволяет решать те же самые задачи, что и программные расширения сервера Web. Страницы ASP представляют собой текстовые файлы с конструкциями языка HTML, классами и сценариями, составленными на таких языках программирования, как JScript и VB Script. Поэтому при условии хороших знаний таких языков программирования как (VB script) написание веб-приложения с использованием технологии ASP не составит труда.

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

1. Регистрация с последующим занесением (e-mail и пароля в базу данных).

2. Введение параметров мониторинга

3. Выбор периода мониторинга

4. Доступ к собранной информации.

Сам пользовательский интерфейс представляет из себя веб-форму, на которой представлены следующая информация:

-главная страница с основной информацией о приложении и необходимыми ссылками на более подробное описание аспектов программы.

-панель быстрого доступа расположенная сверху:

*МИЭМ НИУ ВШЭ — ссылка на главную страницу университета

*Главная — переход на домашнюю страницу

*Информация — более подробные сведения о веб-приложении

*Связаться — мои контакты

*Начать работу — пользовательский интерфейс позволяющий создать, изменить или удалить задачу

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

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

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

Доступ к основному функционалу приложения возможен только после регистрации пользователя. А именно к вкладкам «начать работу» и мой мониторинг».

Весь пользовательский интерфейс был реализован с помощью ASP.net Web-forms.

Рис. 1 Демонстрация веб-сайта, созданного с помощью web-forms

Модель ASP.NET Web Forms изначально проектировалась для того, чтобы реализовать потенциал RAD в среде Web. Таким образом, главным определяющим фактором для большинства основных характеристик и ключевых концепций ASP.NET было стремление к производительности программирования. Модель Web Forms базируется на трех основных концепциях: обратной передаче страниц, состоянии просмотра и серверных элементах управления. Эти три концепции работают совместно в соответствии с моделью, изображенной на рис. 1. Каждый запрос HTTP, передаваемый веб-серверу и сопоставляемый со средой выполнения ASP.NET, проходит несколько стадий, в которых центральное место занимает обработка события обратной передачи (postback). Событие обратной передачи — главное действие, которое ожидает получить пользователь в результате обработки своего запроса.

Рис. 2 модель Web-Forms

Серверные элементы управления играют ключевую роль в модели ASP.NET Web Forms. Вывод страницы ASP.NET определяется в виде комбинации литералов HTML и разметки серверных элементов управления ASP.NET. Серверный элемент управления представляет собой компонент с открытым интерфейсом, который может настраиваться с использованием тегов разметки, дочерних тегов и атрибутов. Каждый серверный элемент управления имеет уникальный идентификатор, который однозначно определяет его. В разметке страницы ASP.NET серверные элементы управления отличаются от простых строковых литералов HTML по наличию атрибута runat. Все теги, не имеющие атрибута runat, интерпретируются как литералы HTML и передаются в выходной поток ответа без дополнительной обработки. Все, что имеет пометку runat, идентифицируется как серверный элемент управления. Серверные элементы управления изолируют пользователя от фактического генерирования кода HTML и JavaScript. Программирование серверного элемента управления сводится к заданию свойств компонента, предназначенного для многократного использования. Однако при обработке серверный элемент управления генерирует код HTML. В конечном итоге программирование серверных элементов управления может рассматриваться как способ получения разметки HTML, не требующий особых знаний о ее специфическом синтаксисе и функциональных возможностях. Серверные элементы управления потребляют информацию состояния просмотра и реализуют события обратной передачи. Кроме того, они отвечают за генерирование разметки, причем делают это, не требуя значительных познаний в области HTML от разработчика.

Пример в приложении А

Подключение базы данных

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

В моем проекте вся работа с БД осуществляется с помощью поставщика баз данных SQL server. Так как она легко взаимодействует с ASP и имеет простой интерфейс управления.

Рис. 3 Вывод содержимого таблицы и меню управления

Создание подключения к базе данных SQL Server не отличается от подключения к любой другой базе данных. Для этого сервер базы данных указывается в качестве локального источника данных. Разработчик может указать файл базы данных для присоединения, используя атрибут строки подключения AttachDBFilename. Подключение к базе данных при помощи имени упрощает развертывание базы данных для приложения (в том случае, если целевой сервер работает под управлением SQL Server, экспресс-выпуск). ASP.NET предоставляет возможность хранения данных в каталоге веб-приложения App_Data. Содержимое каталога App_Data не предоставляется в ответ на веб-запросы, что повышает безопасность данных приложения. Кроме того, разработчик может указать строку подключения |DataDirectory| вместо пути к каталогу приложения App_Data. Функции ASP.NET — например, элементы управления SqlDataSource.

Для удобства использования и во избежание путаницы было создано 2 базы данных:

1. База данных Entities — является стандартной и генерируется автоматически при создании веб-формы, она используется для хранения информации о зарегистрированных пользователях, также в классах и скриптах осуществляется проверка правильности введенной информации. Логин (e-mail пользователя проверки на корректность введённого адреса не проверяется, кроме наличия «@») и пароль пользователя (должен быть введен на латинице, содержать 1 заглавную букву, цифры и строчный знак ( >).

2. База данных NewConnectionString. Была создана для работы с пользователем, в ней содержится информация, внесенная пользователем для мониторинга, а также данные самого мониторинга.

Хочу остановиться подробней на второй базе данных. В ней было создано 2 таблицы:

Таблица Table состоит из следующих столбцов:

-Id — идентификатор необходим для более удобной работы с таблицей, именно к нему обращаются SqlDataSource для создания, правик и удаления строк.

-Name — Название товара мониторинг которого будет вестись

-Refference — полная ссылка на товар

-Pointer — указатель на цену в html коде страницы товара, информацию об указателях можно найти на вкладке веб-приложения » Список поддерживаемых сайтов «.

-Period — Период мониторинга.

Таблица Stat состоит из 4 стобцов:

-Id — идентификатор(аналог таблицы Table)

-Name — имя пользоваетля, именно с помощью данного имени пользователь может следить за ходом мониторинга, так как при наличии мониторинга 2 и более товаров поиск нужного будет осуществляться по этому столбцу.

-Price — цена товара полученная с помощью парсинга html страницы в определенное время

-Time — время когда был совершен парсинг.

По 2 последним столбцам пользователь сможет построить график и увидеть зависимости.

Работа с 1 таблицей осуществлялася с помощью элемента управления данными asp.net, а именно SqlSource. Элементы управления источниками данных включают любые элементы управления, которые реализуют интерфейс IDataSource. С помощью этого элемента было создано подключение к любому источнику данных, который имеет поставщика данных ADO.NET. Сюда относятся и SQL Server.

Рис. 4 Добавление нового элемента в таблицу

Элементы управления источниками данных могут решать две основных задачи:

-применять извлеченные данные к связанным элементам управления;

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

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

Задачи привязки данных возникают в перечисленном ниже порядке:

-Добавляется объект страницы.

-Происходит запуск страницы, а именно события Page.Init и Page.Load.

-любые события элементов управления.

-выполняются обновления элементами управления источниками данных. При обновлении строки, генерируются события Updating и Updated. При вставке — то события Inserting и Inserted. При удалении— Deleting и Deleted.

-Генерируется событие Page.PreRender.

-Страница отображается и освобождается.

Пример в приложении Б и В:

Основной задачей данного пункта создания веб-приложения, является создание логики приложения. А именно парсинг html страницы в .net.

Данный пункт можно было осуществить двумя способами: с помощью регулярного выражения либо с помощью полноценного парсера. Парсер — объектно-ориентированный скриптовый язык программирования, который позволяет генерировать HTML-страницы на веб-сервере и поддерживает CGI. Так как HTML не всегда успешно работает с регулярными выражениями, то был выбран второй вариант реализации.

Существует множество парсеров, самые популярные из них AngleSharp и CsQuery.

CsQuery был одним из самых новых парсеров HTML для .NET. В качестве основы была взята библиотека validator.nu для Java, которая в свою очередь является портом из движка Gecko (Firefox).

AngleSharp В отличие от CsQuery, написан с нуля вручную на C#. Также включает парсеры других языков. API построен на базе официальной спецификации по JavaScript HTML DOM. В некоторых местах есть странности, непривычные для разработчиков на .NET (например, при обращении к неверному индексу в коллекции будет возвращён null, а не выброшено исключение; есть свой отдельный класс Url; пространства имён очень гранулярные).

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

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

Рис. 5 Демонстрация работоспособности парсера

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

Пример в приложении Г

Завершающим этапом создания веб-приложения является реализация выполнения серверных задач по расписанию, а если быть более точным, то через определенный промежуток времени (указывается пользователем). Для выполнения данного пункта использовался Task Scheduler Managed Wrapper.

Это библиотека классов, которая является основным модулем для COM объектов WindowsTaskScheduler. У Данной библиотеки имеется удобный и понятный интерфейс для работы с планировщиком задач. Это open-source проект на языке C#. Библиотека Task Scheduler Managed Wrapper использует scheduler версии 2.0.

В Task Sheduler (далее TS) 2.0 был создан новый пользовательский интерфейс в основу которого положен ManagementConsole. Помимо того, что TS позволяет запускать задачи в определенное время или через определенные интервалы, TS 2.0 также поддерживает триггеры, которые основаны на календарных и прочих событиях, такие как запуск задачи при записи необходимого события в Event Log, или при комбинации событий. Также конфигурация запуска для задач может зависить от состояния системы, например, бездействие системы определенное время, запуск, прекращение сеанса. Также существует расширение xPath, с его помощью можно задать фильтры для событий из Windows Event Log. Задачи также могут приостановлены на определенное время после возникновения события или повторяться пока не возникнет событие. Помимо этого, можно задать последовательность действий, которые будут выполнены, если текущая задача не может быть выполнена. Действия, которые выполняются в ответ на триггеры, могут не только запускать приложения, но и ряд спец. дейтсвий.

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

6. Использованные ресурсы, технологии и подходы

.NET Framework — программная платформа, основой которой является общеязыковая среда исполнения CLR, которая подходит для многих языков программирования. Функциональные возможности данной среды доступны в любых языках программирования, которые используют .NET.

Главной идеей .NET является совместимость частей программы, написанных на разных языках. То есть служба написанная на C++ может вызвать функцию из класса написанного на C#, который наследован от класса написанного на Delphi. Каждая библиотека в .NET имеет информацию о своей версии, это позволяет избежать возвожные конфликты между разными версиями сборок.

Следуя этому подходу приложение разделяется на 3 компонента: вид, модель и контроллер. Есть несколько паттернов проектирования, которые описывают способы, по которым эти компоненты взаимодействуют.

В данном проекте под Вид попадает большая часть User Interface, который представляет собой «косметику», реализованную на ASP.NET в которой содержатся клиентские страницы, а также описания стилей. Под Контроллер попадает оставшаяся часть User Interface, в котором описаны обрботчики событий, реализуемые пользователем (введение данных, клик по кнопке, загрузка страницы…). Под модель попадают все остальные элементы приложения.

Рис. 6 структура MVC подхода

ADO.NET — представляет собой библиотеку классов, основным смыслом которой является упростить работу с данными, в том числе и с СУБД. Также как и ASP является частью .NET.В настоящее время осуществляет поддержку только двух СУБД: MySQL и MS SQL Server. Но несмотря на это приложение позволяет сравнительно легкими путями добавить поддержку других СУБД.

Основное отличие ADO.NET от других API заключается в том, что в ней не происходит прямого взаимодействия с базами данных. Это реализуется с помощью поставщиков данных (data provider), которые инкапсулируют механизм работы с определенной СУБД. Это очень гибкий подход, позволяющий создавать адаптеры для любой СУБД и использовать все ее особенности.

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

1. Был спроектирован веб-интерфейс

2. Была создана база данных для хранения информации о мониторинге, а также информация, введенная пользователем

3. Был реализован алгоритм парсинга HTML страницы, а также поиск цены с помощью селектора

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

5. С помощью Windows Task Sheduler была реализована возможность запуска программы по расписанию.

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

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

Самой сложной в плане реализации частью проекта является этап ScheduleManager. Для версии фреймворка .NET 4.5 и самой последней версии планировщика задач Windows 2.0. Не предусматривается управление задачей без прав администратора. Что более важно, при включенной службе контроля учетных записей пользователей, запрос будет появляться при каждом новом запуске парсера. Поэтому при запуске приложения на другом устройстве может потребоваться небольшая настройка операционной системы.

АРХИТЕКТУРА ВЕБ-ПРИЛОЖЕНИЙ

Особенности разработки современных веб-приложений

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

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

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

В настоящее время принципиально изменились технологии работы компаний в интернете. Теперь все ресурсы интернета размещены на дисках компьютеров, подключенных к сети, т.е. сетевых дисках. Это означает, что мы имеем дело с распределенными сетевыми ресурсами. В случае необходимости получить доступ к информации какого-либо компьютера можно с любого компьютера без обращения к серверу, воспользовавшись сетевыми службами, которые, в свою очередь, также находятся на удаленных сетевых ресурсах. Такие службы называются веб-сервисами. Речь идет о переносе модели «клиент — сервер» на сетевую модель, где сетевая служба сама становится объектом со своими функциями (методами) и атрибутами (свойствами). Вызывая методы этой службы из своих приложений, можно решать различные задачи. Тенденция к появлению специализированных интернет-сервисов (служб) может в будущем привести к тому, что практически отпадет необходимость локального программного обеспечения. Примером могут быть облачные среды разработки приложений IDE (Integrated Development Environment), которые дают возможность с мобильного устройства (смартфона или планшета) разрабатывать приложения на различных языках программирования. К таким IDE относятся, например, EclipseOrion, Cloud 9 IDE, eXoCloudIDE. Переход разработки в «облака» приводит к изменению интерфейса информационных систем — он становится веб-интерфейсом. Общий вывод, который следует из всего изложенного, такой: главное, чтобы концептуально система не устаревала, а на уровне программно-аппаратных средств постоянно происходили бы изменения, порождающие циклический реинжиниринг системы на базе современных технологий.

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

Такая архитектура возможна, если пользователи системы распределены географически в силу естественных причин. Например, основные потребители услуг доступны через интернет (в частности, различные справочные сервисы). Другой пример — система для внутреннего применения компании, ее пользователи также могут быть распределены, но по другим причинам. Сегодня особую актуальность приобретают концепции «мобильных работников» и «домашнего офиса», которые предполагают удаленную работу с основными корпоративными системами. То есть приложения класса ERP должны поддерживать веб-интерфейс. В настоящее время идет массированная миграция традиционных приложений и систем на вебинтерфейсы. Это может быть в виде дополнительных компонент или в виде полной переработки приложения. Так как сценарий работы с распределенными пользователями поддерживается любой системой с веб-интерфейсом, такие приложения называются вебприложениями.

Веб-приложение — это клиент-серверное приложение, в котором клиентом выступает браузер, а сервером — веб-сервер. Логика веб-приложения распределена между сервером и клиентом, хранение данных осуществляется преимущественно на сервере, обмен информацией происходит по сети. Одним из достоинств такого подхода является тот факт, что клиенты не зависят от конкретной операционной системы пользователя, поэтому веб-приложения являются кросс-платформенными сервисами. Переход к веб-приложениям стал очень популярен в конце 1990-х — начале 2000-х гг.

Рассмотрим архитектуру таких веб-приложений на некотором абстрактном примере с использованием конкретных программных средств и выясним, какую роль выполняет каждый компонент (рис. 1.3). В клиентской части приложения специальные компоненты отсутствуют, используются веб-браузер и офисный пакет. [1]

Рис. 1.3. Схема взаимодействия компонентов информационных систем с использованием интернет-технологий 1

С серверной частью все сложнее. Структурно она состоит из трех крупных компонентов:

  • 1) веб-сервера (НТТР-сервера);
  • 2) сервера базы данных (БД);
  • 3) программного интерпретатора.

Веб-сервер является связующим звеном между веб-приложе- нием и клиентом. Он принимает запросы от клиента в виде набора данных по протоколу HTTP и возвращает в ответ документы на языке HTML и файлы, которые требуются дополнительно (картинки, листы стилей, другие объекты). При этом документы и другие файлы могут быть как статическими (находиться в файловой системе сервера), так и динамическими, т.е. сформированными программной частью. Наиболее распространенным веб-сервером является Apache, его используют для организации веб-узлов более чем в 70% случаев (а для русской части интернета этот показатель достигает 90%).

Кроме того, существуют разработки специальных веб-серверов для различных приложений, входящих в большие комплексы, например при использовании веб-приложений на технологиях компании Microsoft используют Internet Information Server (IIS). От выбора сервера зависит набор возможностей по языкам программирования, применяемым для разработки информационной системы.

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

Программный интерпретатор — это сердце системы. С помощью программного интерпретатора выполняется код, содержащий логику работы системы (алгоритмы). Поясним, почему этот элемент называется именно так. В веб-среде могут выполняться приложения, написанные на различных языках программирования. Их можно разделить на две группы: компилируемые (исполняемые как обычные программы на компьютере) и интерпретируемые (требующие интерпретатора для выполнения). При разработке веб-приложений используются оба этих типа, но особую популярность заслужили именно интерпретируемые языки: Perl, PHP, Ruby, Python. Интерпретируемые программы медленнее выполняются, но процесс их разработки значительно проще и быстрее. Учитывая постоянно повышающиеся требования бизнеса на скорость внедрения изменений в программные продукты (информационные системы), быстрый цикл разработки программ становится решающим фактором. Кроме того, мощность компьютеров постоянно возрастает, позволяя до определенного предела забывать о производительности приложений в угоду удобству и скорости разработки.

В приведенном на рис. 1.3 примере используется интерпретируемый язык Рег1 как мощный и подходящий для большинства проектов по созданию информационных систем с веб-интерфейсом. Программный код системы состоит из модулей и скриптов. Эти два компонента реализуют логику выполнения и основную функциональность системы.

Выбор языка Рег1 обусловлен следующими факторами:

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

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

Сервер баз данных выполняет накопление структурированной информации, а также ее выдачу по запросам веб-приложения. При этом между программной частью системы и сервером баз данных могут использоваться различные интерфейсы (как стандартные, так и специальные). Не все языки программирования веб-приложений имеют надежные и функциональные интерфейсы к серверам баз данных различных разработчиков. От сервера баз данных зависят производительность приложения и функциональность с точки зрения данных. Например, развитые СУБД позволяют использовать распределенные хранилища данных и имеют мощные возможности по защите от сбоев и восстановлению после них. На рис. 1.3 представлена в качестве примера СУБД MySQL, имеющая серьезную репутацию в мире веб-разработок.

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

Проблема некорректного отображения обусловлена тем, что совместимость браузеров с международными стандартами не является полной, т.е. при создании HTML-кода страниц и приложений нужно учитывать особенности каждого из числа основных веббраузеров, используемых на рынке (MS Internet Explorer, Chrome, Opera, FireFox, Safari). При этом нет гарантии, что протестированное на основных видах браузеров приложение будет корректно работать на других, более редких, продуктах.

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

Использование мобильных устройств. В настоящее время с появлением мобильных устройств клиентом веб-сервера может быть не только персональный компьютер, оснащенный обычным веббраузером, но и собственно мобильное устройство. Мобильные устройства обладают характеристиками, отличными от характеристик персональных компьютеров. Они имеют ограниченного размера экран, малый объем памяти, а нередко и невозможность отобразить что-либо, кроме нескольких строк черно-белого текста. В настоящее время для них существуют другие протоколы передачи данных, например WAP (Wireless Access Protocol), и соответствующие языки разметки, например, WML (Wireless Markup Language)

и CHTML (Compact HTML). Для передачи данных на мобильное устройство соответствующего формата используются специальные сайты, поддерживающие WAP и WML. Наиболее перспективными являются приложения, которые в зависимости от типа клиента умеют генерировать тот или иной код. Именно такой подход реализован в технологии Microsoft ASP.NET.

Разделение бизнес-логики и интерфейса. С ростом объема используемых данных и числа посетителей сайта возрастают и требования к надежности, производительности и масштабируемости веб-приложений. Для удовлетворения указанных требований бизнес-логику, которая реализована в веб-приложениях, отделяют от интерфейса приложения и переносят на сервер приложений в виде независимых бизнес-объектов, которые могут быть реализованы в одной из известных технологий: СОМ, Microsoft.NET и др. Часто такие бизнес-объекты реализуют какую-либо часть функциональности информационной системы (не конкретной системы, а предоставляют модуль или часть модуля, которые можно «вживлять» в любую информационную систему). Такие бизнес-объекты могут представлять веб-сервисы.

Как было сказано ранее, практически все бизнес-приложения, разрабатываемые в настоящее время, являются распределенными. На рис. 1.4 представлена схема взаимодействия сайтов в интернете с использованием распределенного веб-приложения.

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL