Научная статья на тему 'Разработка и внедрение интерпретатора декларативного языка моделирования web-интерфейсов на высоконагруженных системах'

Разработка и внедрение интерпретатора декларативного языка моделирования web-интерфейсов на высоконагруженных системах Текст научной статьи по специальности «Компьютерные и информационные науки»

CC BY
684
97
i Надоели баннеры? Вы всегда можете отключить рекламу.
Ключевые слова
WEB / СЕРВЕРНОЕ ПРОГРАММИРОВАНИЕ / SERVER PROGRAMMING / ВЫСОКОНАГРУЖЕННЫЕ СИСТЕМЫ / ОБЛАЧНЫЕ ВЫЧИСЛЕНИЯ / CLOUD COMPUTING / КЛАСТЕРЫ / CLUSTERS / СЕРВЕРЫ / SERVERS / ИНТЕРПРЕТАТОР / INTERPRETER / ДЕКЛАРАТИВНОЕ ПРОГРАММИРОВАНИЕ / DECLARATIVE PROGRAMMING / BML / BLOCKSET / CGI / FASTCGI / HTML / XML / MVC / C++ / BACKEND / HIGHLOAD SYSTEMS

Аннотация научной статьи по компьютерным и информационным наукам, автор научной работы — Кейно П.П., Силуянов А.В.

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

i Надоели баннеры? Вы всегда можете отключить рекламу.

Похожие темы научных работ по компьютерным и информационным наукам , автор научной работы — Кейно П.П., Силуянов А.В.

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.
i Надоели баннеры? Вы всегда можете отключить рекламу.

Design and implementation of a declarative web-interface modeling language interpreter on a high-performance distributed systems

The article examines the development process of the BML interpreter and the high-performance cluster building with BML support. The language allows to modeling a web-interfaces and their business logic in a declarative form. The article contains the comparative analysis of some critical components in the system. In particularly there is a comparison of efficiency of the Web platforms in static and dynamic environments between CGI, FastCGI and traditional PHP programming. Efficiency of compiling and interpreting languages also considered. According to study, the Fast CGI platform with the C++ language gives the best result of performance. Detailed architecture with the base system components is considered. The interpreter contains low-level programming elements and requires performing the following tasks: HTTP requests parsing, store and retrieve user sessions, interact with DBMS, parsing of XML-like documents, processing a regular expressions, provide the computed data to templates and etc. There are some resource-intensive processes in the interpreter and they are also requiring detailed analysis. The BML language based on XML syntax therefore its interpreter require a proper XML-parser. Authors chose libxml2 as the best way for the fast development although it shown not highest efficiency. Some of components are developed independently: HTTP-parser, configuration files parser, session manager, all interface classes and more. In the article presented the development process of the interpreter in high-performance systems as complex engineering solution.

Текст научной работы на тему «Разработка и внедрение интерпретатора декларативного языка моделирования web-интерфейсов на высоконагруженных системах»

Том 10. № 1 (55). 2015

П. П. Кейно, преподаватель кафедры «Системное моделирование и инженерная графика» ФГБОУ ВПО «МАТИ — Российского государственного технологического университета им. К. Э. Циолковского»,

г. Москва, pavel@keyno.com

А. В. Силуянов, канд. техн. наук, профессор, доцент кафедры «Системное моделирование и инженерная графика» ФГБОУ ВПО «МАТИ — Российского государственного технологического университета

им. К. Э. Циолковского», г. Москва, ctcmati@yandex.ru

Разработка и внедрение интерпретатора декларативного языка моделирования Web-интерфейсов на высоконагруженных системах

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

Ключевые слова: Web, серверное программирование, высоконагруженные системы, облачные вычисления, кластеры, серверы, интерпретатор, декларативное программирование, BML, BlockSet, CGI, FastCGI, HTML, XML, MVC, C++.

введение

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

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

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

\ 55

Vol. 10. No. 1 (55). 2015

памяти, процессорного времени. Растет также интенсивность операций чтения / записи на диск. При исчерпании системных ресурсов сервера происходит замедление обслуживания клиентских запросов, что создает дополнительную очередь подключений. В результате происходит цепная реакция, очередь запросов возрастает до таких пределов, что сервер не может функционировать в штатном режиме и в конечном итоге прекращает обслуживание. Главной задачей инженеров по проектированию высоко-нагруженных систем является перераспределение уровней нагрузки таким образом, чтобы основная часть запросов обслуживалась легковесными сервисами, оперирующими быстрой памятью. При этом не должна пострадать бизнес-логика приложения, работающего в данном программно-аппаратном комплексе. Качественная характеристика высоконагруженной системы выражается в количестве запросов, которое система может обслужить за единицу времени, как правило, равную одной секунде. Система считается высоконагруженной, если способна обслужить от 150 запросов/с [2]. Конечно, установленные границы весьма условны, так как ресурсоемкость каждого запроса может зависеть от многих факторов, в том числе от типа запроса (на чтение или на запись), параметров выдачи содержимого (статически или динамически), использования кэширования и ряда других параметров.

0 проекте

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

самого интерпретатора, так и на уровне сопутствующих системных сервисов.

Интерпретатор был разработан в качестве практической реализации методологии BlockSet, предложенной авторами ранее [3]. Методология призвана повысить эффективность Web-разработки узлов различной степени сложности путем перераспределения уровней абстракции данных. Описанный выше язык носит название BML (англ. BlockSet Modeling Language, моделирующий язык BlockSet), основанный на XML-совместимом синтаксисе. С помощью BML задается логика работы приложения в декларативном виде. Интерпретатор исполняет заданную логику, на ее основе получает необходимые данные, а затем поставляет их шаблониза-тору, который, в свою очередь, «склеивает» их с шаблоном и передает в браузер в виде документа HTML или любом другом формате. В работе по большей части будут рассмотрены технологии оптимизации каждого звена разрабатываемой системы и попутно объяснено их предназначение для понимания сути методологии BlockSet.

Архитектура Web-сервиса

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

Предполагается, что будущий Web-сервис будет способен обслужить до 100 тыс. пользователей за сутки. Если принять во внимание, что один пользователь совершает от 10 до 150 запросов, получаем усредненное значение общего количества запросов за сутки, которое система должна обработать: около 8 млн. Логично предположить, что суточный пользовательский трафик не распределен равномерно во времени. Чтобы в этом убедиться, достаточно взглянуть на суточную статистику крупнейшей московской точки обмена трафиком в России MSK-IX [5]. Пользовательский трафик напрямую связан с числом пользователь-

Том 10. № 1 (55). 2015

ских запросов, поэтому существует прямая корреляция между этими двумя характеристиками. На основе полученной кривой можно спрогнозировать пиковую нагрузку, посильную для системы, составив пропорцию трафика и числа запросов. Допустим, средняя пропускная способность точки обмена трафиком 816 549 Мбит/с, максимальная — 1 460 756 Мбит/с. Разделим на количество секунд в сутках 8 млн запросов: 8 000 000/24/60/60 = 92 запроса/с. Получаем среднюю пропускную способность системы. Исходя из вышеупомянутой корреляции, нетрудно составить пропорцию между средним и максимальным отношением трафика к числу запросов:

816 549 Мбит/с _1 460 756 Мбит/с

92 запросов/с x '

x ~ 164 запроса/с.

Таким образом, при заявленном начальном условии, что разрабатываемый сервис будет обслуживать 100 тыс. пользователей в сутки, пиковая нагрузка для него будет приблизительно равна 164 запроса/с при идеальных условиях. Разумеется, к этому числу следует добавить определенный ресурсный запас, так как объем трафика (а следовательно, и число запросов) любого Web-узла носит флуктуационный характер и может зависеть от множества временных и событийных факторов: дня недели, времени года, календарного праздника, появления определенного события глобального масштаба, размещения ссылки на сервис на крупном интернет-ресурсе и др. Как бы там ни было, представленная система является высоконагруженной, а значит, требует построения соответствующей архитектуры.

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

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

Слой представления

Серверы Frontend представляют собой промежуточное звено между клиентом и слоем основной логики приложения и предназначены для хранения статических ресурсов, а также перенаправления сложных запросов на Backend-серверы. Серверы Frontend-кластера полностью дублируют друг друга с целью балансировки нагрузки, на них установлен легковесный Web-сервер nginx с идентичными настройками. Нагрузка таких серверов распределяется равномерно по циклическому алгоритму round-robin на уровне службы доменных имен (DNS) [6]. Суть этого алгоритма заключается в последовательном обращении к каждому из серверов. Рассмотрим пример системы с тремя серверами. В файле зоны DNS-сервера хранится три адресных записи IP (A-записи) для каждого из Web-серверов. Система DNS, выполняя роль резолвера IP-адреса, будет возвращать каждому вновь обратившемуся клиенту следующий по цепочке адрес. То есть третьему обратившемуся клиенту будет возвращен третий адрес, четвертому — первый и так далее по кругу. Таким образом, нагрузка на серверы распределяется строго равномерно, что позволяет увеличивать количество серверов прямо пропорционально нагрузке. Такое увеличение носит название «горизонтальное масштабирование» [7].

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

v_57

Vol. 10. No. 1 (55). 2015

Клиент

Рис. 1. Проект архитектуры серверной части Fig. 1. Server-side architecture proposition

Том 10. № 1 (55). 2015

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

Слой бизнес-логики

На слое бизнес-логики (кластер Backend) построен весь функционал основного приложения. Как правило, слой бизнес-логики гораздо шире слоя представления, так как большинство вычислительных мощностей сосредоточено именно на нем. Сервер nginx Frontend^ подключается к одному из серверов Backend^. В качестве Web-сервера используется Apache v. 2.2. На тяжеловесном слое бизнес-логики выполняются основные вычисления, осуществляются запросы к слою данных. После выполнения вычислений данные передаются обратно в слой представления.

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

Облачный Web-сервис предоставляет возможность пользователю создать собственный Web-узел [4]. Пользователь может зарегистрировать на сервисе доменное имя

третьего уровня вида username.domain.tld, где username — имя, выбираемое пользователем; domain.tld — домен второго уровня, на котором расположен Web-сервис. Согласно вышесказанному, горизонтальное масштабирование с простейшим зеркали-рованием серверов бизнес-логики работать не будет, так как на этих серверах хранятся совершенно разные пользовательские данные.

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

Рассмотрим подобный способ масштабирования на примере адреса pavel.blockset.ru. Предположим, на слое бизнес-логики существует 10 серверов. Для простоты будем использовать хеш MD5, хотя подойдет абсолютно любой алгоритм хеширования. Возьмем хеш от хоста: MD5("pavel.blockset.ru") = = 9aa0...72b62. Хеш представляется в виде числа в шестнадцатеричной системе счисления. Первая цифра этого числа равна 9, которая, для удобства восприятия, в таблице соответствия ссылается на девятый сервер. Тогда цифра «a», в случае с другим хостом, будет соответствовать десятому серверу, а «b» — снова первому. При получении одной цифры, взятой из хеша, масштабирование ограничено шестнадцатью серверами, тогда как использование двух цифр расширяет потенциальное количество серверов в кластере до 256. Увели-

\ 59

Vol. 10. No. 1 (55). 2015

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

Слой данных

Слой данных содержит в себе многоуровневую архитектуру серверов СУБД с одним master-сервером. Через master-сервер происходит запись в базу данных. Затем обновленные данные реплицируются на все slave-сервера, с которых впоследствии происходит чтение. Поскольку большинство запросов поступает именно на чтение, в высо-конагруженных системах распространена практика горизонтального масштабирования slave-серверов по такой же схеме, как у Frontend-кластера.

Кроме того, на слое данных присутствует сервер memcached, используемый для кэширования часто используемых данных, генерируемых слоем бизнес-логики. Интерпретатор часто кэширует данные на этапе разбора BML-документов и на этапе выборки из БД. Использование memcached для этих целей является оптимальным, так как

данная технология использует хранение данных в ОЗУ и представляет собой стандартное NoSQL-хранилище типа «ключ-значение».

структура интерпретатора

Интерпретатор BML — комплексная система, предназначенная для обработки исходного кода языка BML и генерации данных на основе логики, записанной на этом языке. Структурная схема в общем виде представлена на рис. 2.

Ядро интерпретатора — основной компонент системы, управляющий множеством вспомогательных компонентов. В первую очередь Web-сервер передает данные (переменные окружения, Cookie, заголовки запроса, данные форм GET и POST) с помощью интерфейса FastCGI. Задача HTTP-обработчика — обработать эти данные и представить их через интерфейсный компонент ядру интерпретатора в удобочитаемой форме. Кроме того, в задачи обработчика HTTP входит также получение данных пользовательской сессии через специали-

Передача документа в браузер

Рис. 2. Общая схема работы интерпретатора языка BML Fig. 2. General flowchart of the BML interpreter

60

Том 10. № 1 (55). 2015

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

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

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

Касаемо баз данных изначально была выбрана СУБД MySQL как наиболее простая, не требующая больших временных затрат на установку и поддержку, открытая, при этом удовлетворяющая требованиям, предъявляемым к высоконагруженным системам среднего уровня. Для связи программного модуля с СУБД было принято решение использовать официальную библиотеку MySQL Connector (mysqlclient).

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

представленной системы без использования сторонних библиотек. К первому типу относится задача реализации обработки Perl-совместимых регулярных выражений. В языке C/C++ в большинстве случаев используется библиотека PCRE, которая и была внедрена в проект. Ко второму типу относятся компоненты чтения конфигурационных файлов, обработки данных HTTP, механизма работы сессий. Они реализованы самостоятельно строго с тем набором функций, который необходим в рамках работы интерпретатора.

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

имитационные испытания

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

Испытания будут проводиться на сервере под управлением FreeBSD 8.2 amd64 со следующими техническими характеристиками: четырехъядерный процессор Intel Xeon E5640 с тактовой частотой 2,66 ГГц, объемом ОЗУ 1 Гб и объемом жесткого диска 250 Гб.

На испытываемом оборудовании установлен Web-сервер nginx 0.8.54, работающий по принципу конечного автомата (FSM). Как и в большинстве Web-серверов, в nginx

v_61

Vol. 10. No. 1 (55). 2015

имеется поддержка CGI и FastCGI. Для проведения дополнительного эксперимента с динамической генерацией данных на испытуемой машине использовался также интерпретатор скриптового языка PHP 5.3.28. Все тестовые программы, написанные на C/C++, были собраны компилятором gcc/g++ 4.2.1.

выбор языка программирования и динамической Web-платформы

При выборе языка программирования авторы руководствовались следующими основными критериями: быстродействие, минимальный расход памяти и эффективность разработки. Поскольку речь идет о разработке интерпретатора — программы, обрабатывающей большие объемы однотипных данных, решено было использовать компилируемый язык программирования как наиболее производительный. Следовательно, интерпретируемые языки вроде Perl, PHP, Python или Ruby для решения поставленной задачи не подходят, так как эффективность исполнения кода у них на несколько порядков ниже. Помимо этого, важным аспектом является гибкость в использовании протокола HTTP, прямая работа с системными вызовами, потоками и другими низкоуровневыми сущностями. Выбор сократился до двух претендентов: C++ и Java. Последний имеет относительно низкий порог вхождения и высокую эффективность разработки. Если говорить о скорости выполнения программ, то большая часть алгоритмов на C++ выполняется так или иначе быстрее, а в некоторых случаях сопоставимо по затрачиваемому времени. Однако Java значительно проигрывает C++ по критерию потребляемой памяти [8] за счет вовлечения дополнительного звена — Java-машины. В итоге программный модуль интерпретатора решено было исполнить на языке C++.

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

ром динамической Web-платформы [9]: CGI или FastCGI. Также существует технология создания собственного модуля для Web-сервера, однако мы ее оставим за рамками данной статьи по причине отсутствия универсальности решения. Это означает, что при смене Web-сервера придется перестраивать архитектуру проекта заново, а учитывая тот факт, что каждый Web-сервер имеет свой собственный специфичный программный интерфейс (API), порог вхождения в технологию снижается до минимума. Следовательно, могут возникнуть трудности при поиске специалистов соответствующего профиля, способных поддержать программный код.

CGI

Интерфейс CGI (англ. Common Gateway Interface) [10] является одним из первых решений, позволивших сделать Web-сервер динамическим. Он обеспечивает связь между внешней программой операционной системы и Web-сервером. Интерфейс и сейчас является одним из самых распространенных для взаимодействия с внешними приложениями сервера. В числе его достоинств — относительная простота разработки. Входные данные подаются через стандартный поток ввода, а выходные возвращаются через стандартный поток вывода. Потоки данных и переменные окружения может обрабатывать любой распространенный язык программирования. Запуск CGI-программ полностью поддерживается большинством серверов.

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

Том 10. № 1 (55). 2015

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

FastCGI

В FastCGI [11] решены проблемы предыдущей технологии. Процессы теперь не порождаются при каждом новом соединении, а создаются при запуске Web-сервера и находятся в памяти, ожидая входящих подключений. Когда Web-сервер получает новый запрос, требующий динамической обработки, он инициирует соединение с процессом FastCGI и перенаправляет ему все запрашиваемые данные. По завершении обработки запроса процесс отправляет данные обратно Web-серверу по тому же соединению, которое, в свою очередь, отдает их браузеру. Web-сервер закрывает соединение, и процесс FastCGI возвращается в пул, ожидая нового подключения. Таким образом, технология FastCGI сводит к нулю накладные расходы на порождение новых процессов, улучшая производительность в сравнении с CGI.

Нагрузочное тестирование Web-платформ

Для выявления наилучшего решения по выбору Web-платформы мы будем использовать утилиту нагрузочного тестирования Siege [12], имитирующую приток пользователей на сервер. Режимы работы и количество имитируемых пользователей задаются через командную строку при запуске. Запуск утилиты будет проводиться на той же

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

В первом испытании будет проведено нагрузочное тестирование сервера, возвращающего статическую страницу в формате HTML фиксированного размера — около 16 КБ. Тестирование выявит объем прямых накладных расходов при работе в различных режимах. Статический контент будет отправляться с использованием FastCGI и CGI, а также интерпретатора PHP, исполняемого через модуль Web-сервера Apache. Кроме того, в качестве эталона будет использован реально существующий файл HTML, расположенный на физическом носителе сервера и отправляемый напрямую Web-сервером без использования сторонних интерфейсов. Испытание покажет рост накладных расходов, возникающих при использовании динамических Web-платформ относительно эталона. Любое кэширование, как на стороне клиента, так и на стороне сервера, будет отключено. Результаты тестирования показаны на рис. 3.

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

- 1800

>

о 1600

о -L

I _0 с; Ф Ф о 1400 1200

н ^ ш 1000

гг п 800

о о

m о

со ÍX 600

s

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

о £Х я со 400

L 200 0

HTML PHP

Static CGI Static FastCGI

10

20

50

100

150

Количество пользователей

Рис. 3. Испытание Web-платформ со статическим содержимым Fig. 3. Web-platform benchmarking with the static content

63

-ч ПРИКЛАДНАЯ ИНФОРМАТИКА / JOURNAL OF APPLIED INFORMATICS

Vol. 10. No. 1 (55). 2015 '

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

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

В ходе второго испытания содержимое страницы будет генерироваться динамически. Для этого был написан специализированный скрипт на языке PHP и три программных модуля на языке C++ для режимов CGI и FastCGI. Для последнего было осуществле-

но две реализации: с использованием библиотек fcgi и fastcgi++. Разница в результатах их тестирования оказалась незначительной, поэтому для технологии FastCGI было решено рассматривать только один программный модуль — на основе библиотеки fcgi. Для обеспечения полноты проведения испытания на вход испытуемых модулей методом GET подавалось пять параметров со случайным набором символов латиницы фиксированной длины как в имени параметра, так и в его значении. Над этими параметрами выполнялись примитивные математические и логические операции: сложение, вычитание, запись в массивы. Результаты всех операций выводились в браузер. Получаемая страница по объему была сравнима со статической страницей из предыдущего испытания. Кроме того, сами параметры, в случае с CGI и FastCGI, необходимо было вручную получить и обработать. Для этого была написана собственная библиотека обработки HTTP-запросов. В ней реализован стандартный алгоритм конечного автомата. Результаты тестирования представлены на рис. 4.

На диаграмме результаты тестирования HTML взяты из предыдущего испытания и являются также эталоном, хотя и весьма условным. Технология CGI снова показывает крайне низкий результат тестирования. Количество запросов, обрабатываемых с ее помощью, снизилось примерно в 1,5 раза в сравнении с отдачей статического содержимого из предыдущего теста. Однако, не-

- 1800

1— о > cT 1600

о 1

X 1400

с; Ф о 1200

H m 1000

S _Û о 800

m о 600

m ÎX

^ i_

о я 400

IX w

IZ 200 0

10 20 50 100 150 Количество пользователей

HTML PHP

Dynamic CGI Dynamic FastCGI

Рис. 4. Испытание Web-платформ с динамическим содержимым Fig. 4. Web-platform benchmarking with the dynamic content

Том 10. № 1 (55). 2015

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

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

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

выбор синтаксического анализатора XML

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

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

В статье [13] детально рассмотрены тесты распространенных синтаксических анализаторов XML. Авторами указанной статьи проведен ряд тестов производительности по различным характеристикам. В частности, проведен тест, в котором измерено время разбора после 20 запусков и обработки простейшего файла. Результаты показаны на рис. 5.

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

В следующем тесте из упомянутой выше статьи [13] демонстрируется разбор XML-документов переменного размера (рис. 6). Обрабатывались документы в широком размерном диапазоне, начиная от 277 Кб (workflow_PIW.xml) и заканчивая 4,9 Мб (hapmap_1797SNPs.xml).Тест проводился на протяжении 20 запусков. Расчетный средний суммарный объем BML-документов для одного проекта не будет превышать 300 Кб, поэтому наиболее точно отражает эффективность работы интерпретатора исследование разбора файла workflow_PIW.xml, время процессинга которого во всех тестах, кроме теста анализатора xercer, не превышает 2 с. Однако один проект может содержать множество документов BML, вот почему важно обратить внимание и на предыдущий тест накладных расходов при загрузке и выгрузке анализатора, где ситуация уже не столь однозначная.

Наилучший показатель производительности по накладным расходам показала библиотека gsoap, однако было принято решение отказаться от нее, так как она рас-

\ 65

Vol. 10. No. 1 (55). 2015

я

ф ^

n

о m i=t о

О ,_

'S « 2 ra

ф m

— —

п

* P ^ Jf

PX

* / o

* ^ ?" <5*

* ^ + ^. ^ J>

V f à y à ¿y # Jf' <<y

Рис. 5. Анализ накладных расходов некоторых синтаксических анализаторов Fig. 5. Overhead of some XML parsers

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

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

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

Библиотека xpp3 (XML Pull Parsing) предназначена для разработки на языке Java, поэтому не может рассматриваться в качестве практического решения. Кроме того, поддержка библиотеки уже более десяти лет не производится. Библиотека mono не подошла по той же причине, что и предыдущее решение: реализация на другом языке программирования — в данном случае C#.

i

ф s

i? о ч я

£Х О VO СО

я

12 000 10000

m 8000 о

6000

о

с^ 4000

Я со

ф m

2000 0

□ hapmap_1797SNPs.xml

□ molecule_1kzk.pretty.xml

□ workflow_Atype.xml ■ workflow_PIW.xml

О

ï>-'

Рис. 6. Анализ времени разбора XML-документов различного размера Fig. 6. XML parsing performance with a various document size

8

7

6

5

4

3

2

0

бб

Том 10. № 1 (55). 2015

Наиболее практичным решением и в части производительности, и с позиции удобства разработчика является библиотека libxml2. Она работает по принципу «черного ящика», когда на вход подается XML-документ, а на выходе выводится объект, с которым будет производиться дальнейшая работа. К дополнительным преимуществам можно отнести упрощенную переносимость библиотеки на другие платформы, так как она использует стандартный код ANSI C. Именно библиотека libxml2 была выбрана в качестве синтаксического анализатора кода BML.

iНе можете найти то, что вам нужно? Попробуйте сервис подбора литературы.

выбор шаблонизатора

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

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

10 000 9000 3 ? 8000 7000 6000 5000 4000 3000 2000 1000 0

Шаблонизаторы

о ю

СО о

о о ср

о ^

О

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

В статье [14] представлен детальный сравнительный анализ шаблонизаторов, разработанных на основе парадигмы конвейерной обработки [15] и не использующих функции обратного вызова. Для тестирования каждого шаблонизатора применялся тест «Lebowski Bench», во время прохождения которого генерировался документ HTML, в котором присутствуют элементы «традиционной» Web-страницы: разделы сайта, лента новостей, навигационные теги и др. Тесты используют одинаковый набор данных. Для каждого шаблонизатора создавался собственный шаблон таким образом, чтобы конечный результат максимально совпадал с исходной Web-страницей. Результаты тестирования представлены на рис. 7.

Как видно из диаграммы, шаблонизатор CTPP2 с большим отрывом превосходит остальные по производительности. При этом он поддерживает основной функционал, используемый в шаблонах: вставку внешних шаблонов, циклы, ветвления, именованные блоки и др. Исходный код программной платформы написан на C++ и распространяется по лицензии BSD, что никак не ограничивает использование платформы в настоящей работе. Кроме того, шаблонизатор поддерживает ком-

■ Template Toolkit

□ HTML::Template

□ HTML::Template::Pro

□ HTML::Template::Compiled

□ HTML::Template::JIT

□ HTML::CTPP2

Рис. 7. Результаты тестирования шаблонизаторов Fig. 7. Template engines benchmarking results

67

Vol. 10. No. 1 (55). 2015

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

выводы

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

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

Произведен сравнительный анализ языков программирования с учетом следующих требований: высокая производительность, низкие накладные расходы на выполнение разработанных программ, кроссплатфор-менность, открытость. В конечном итоге выбран язык программирования C++. Проведено тестирование динамических Web-платформ CGI и FastCGI наряду с интерпретируемым языком PHP и статической страницей HTML, взятой в качестве эталона. Проводились тесты вывода статического (прогревочные тесты динамических платформ) и динамического содержимого. Лучшие показатели работы на высоких нагрузках показала платформа FastCGI. Однако CGI как наиболее распространенная и надежная платформа, являющаяся в некотором смысле родственником FastCGI, была также поддержана в рамках разрабатываемого проекта, несмотря на низкую эффективность.

Детально рассмотрена архитектура интерпретатора в базовой сборке. Проведен

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

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

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

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

68

Том 10. № 1 (55). 2015

Список литературы

1. Dhamdhere A., Luckie M, Huffaker B, Claffy K, Elmokashfi A. and Aben E. Measuring the Deployment of IPv6: Topology, Routing and Performance // IMC '12 Proceedings of the 2012 ACM conference on Internet measurement conference. N. Y., USA, 2012, pp. 537-550.

2. Le M, Stavrou A. and Kang B. B. DoubleGuard: Detecting Intrusions In Multi-tier Web Applications // Dependable and Secure Computing, IEEE Transactions on, vol. 9, no. 4, Nov 2011, pp. 512-525.

3. Кейно П. П., Силуянов А. В. Автоматизированная разработка динамических Web-узлов средствами декларативного языка программирования // Прикладная информатика. 2014. № 6. С. 70-78.

4. Кейно П. П. Визуальный редактор BlockSet. Свидетельство о государственной регистрации программы для ЭВМ 2014662832, Dec 10, 2014.

5. TrafficStatistics // MSK-IX. 2014. URL: http:/ / www.msk-ix.ru/ eng/ traffic.html (дата обращения: 28.12.2014).

6. Borkar G. M., Pund M. A. and Jawade. Implementation of round robin policy in DNS for thresholding of distributed web server system // ICWET '11 Proceedings of the International Conference & Workshop on Emerging Trends in Technology. N. Y., USA, 2011, pp. 198-201.

7. Jayasinghe D., Malkowski S., Wang Q., Li J., Xiong P. and Pu C. Variations in Performance and Scalability When Migrating n-Tier Applications to Different Clouds // Cloud Computing (CLOUD), 2011 IEEE International Conference on. Washington, DC, USA, 2011, pp. 73-80.

8. Java vs C++ g++ // Computer Language Benchmarks Game. URL: http://benchmarksgame.alioth. debian.org/u32q/benchmark.php?test=all&lang= java (дата обращения: 09.12.2014).

9. Hansen T., Apte V. and Reeser P. Performance comparison of dynamic web platforms // Computer Communications, 2003, pp. 888-898.

10. CGI: Common Gateway Interface // W3C. 1995. URL: http://www.w3.org/CGI/ (дата обращения: 10.12.2014).

11. FastCGI: A High Performance Web Server Interface, Technical White Paper by Open Market, Inc. 1996. URL: http://www.fastcgi.com/devkit/doc/ fastcgi-whitepaper/fastcgi. htm (дата обращения: 10.12.2014).

12. Fulmer J. Siege User's Manual // Joe Dog Software. 2012. URL: http://www.joedog.org/siege-manual/ (дата обращения: 16.12.2014).

13. Head M. R., Madhusudhan G., Engelen R. V. and Zhang W. Benchmarking XML Processors for Applications in Grid Web Services // SC 2006 Conference, Proceedings of the ACM/IEEE. Tampa, FL. Nov 2006, р. 30.

14. Шетухин А. Тесты производительности // Шаблонизатор CTPP. URL: http://ctpp.havoc.ru/ template_benchmarks. html (дата обращения: 08.01.2015).

15. Xu K., Zhang S., Feng Y. and Zhao D. Answering Natural Language Questions via Phrasal Semantic Parsing // Natural Language Processing and Chinese Computing, vol. 496, Dec 2014, pp. 333-344.

References

1. Dhamdhere A., Luckie M., Huffaker B., Claffy K., Elmokashfi A., and Aben E. Measuring the Deployment of IPv6: Topology, Routing and Performance. IMC '12 Proceedings of the 2012 ACM conference on Internet measurement conference. N. Y., USA, 2012, pp. 537-550.

2. Le M., Stavrou A. and Kang B. B. Double Guard: Detecting Intrusions In Multi-tier Web Applications. Dependable and Secure Computing, IEEE Transactions on, vol. 9, no. 4, Nov 2011, pp. 512-525.

3. Keyno P. P., Siluyanov A. V. Avtomatizirovannaja razrabotka dinamicheskih Web-uzlov sredstvami deklarativnogo jazyka programmirovanija [Automated Development of Dynamic Websites by Using Declarative Programming Language]. Priklad-naja informatika — Journal of Applied Informatics, 2014, no. 6, pp. 70-78.

4. Keyno P. P. Vizual'nyj redactor BlockSet. Svidetel'stvo o gosudarstvennoj registracii pro-grammy dlja JeVM [BlockSet Visual Editor. Certificate of state registration of the computer program] № 2014662832, Dec 10, 2014.

5. Traffic Statistics. MSK-IX. 2014. (URL: http://www. msk-ix.ru/eng/traffic. html (accessed: 28.12.2014)).

6. Borkar G. M., Pund M. A. and Jawade. Implementation of round robin policy in DNS for thresholding of distributed web server system. ICWET '11 Proceedings of the International Conference & Workshop on Emerging Trends in Technology. N. Y., USA, 2011, pp. 198-201.

\ 69

Vol. 10. No. 1 (55). 2015

7. Jayasinghe D., Malkowski S., Wang Q., Li J., Xiong P. and Pu C. Variations in Performance and Scalability When Migrating n-Tier Applications to Different Clouds. Cloud Computing (CLOUD), 2011 IEEE International Conference on. Washington, DC, USA, 2011, pp. 73-80.

8. Java vs C++ g++. Computer Language Benchmarks Game. URL: httpY/benchmarksgame.alioth. debian.org/u32q/benchmark.php? test=all&lang= java (accessed: 09.12.2014).

9. Hansen T., Apte V. and Reeser P. Performance comparison of dynamic web platforms. Computer Communications, 2003, pp. 888-898.

10. CGI: Common Gateway Interface. W3C, 1995. URL: http://www.w3.org/CGI/ (accessed: 10.12.2014).

11. FastCGI: A High Performance Web Server Interface, Technical White Paper by Open Market, Inc., 1996. URL: http://www.fastcgi.com/devkit/

doc/fastcgi-whitepaper/fastcgi. htm (accessed: 10.12.2014).

12. Fulmer J. Siege User's Manual. Joe Dog Software, 2012. URL: http://www.joedog.org/siege-manual/ (accessed: 16.12.2014).

13. Head M. R., Madhusudhan G., Engelen R. V. and Zhang W. Benchmarking XML Processors for Applications in Grid Web Services. SC 2006 Conference, Proceedings of the ACM/IEEE. Tampa, FL. Nov 2006, p. 30.

14. Shetuhin A. Testy proizvoditel'nosti. Shabloniza-tor CTPP [CTPP template engine benchmarking]. URL: http://ctpp.havoc.ru/template_benchmarks. html (accessed: 08.01.2015).

15. Xu K., Zhang S., Feng Y. and Zhao D. Answering Natural Language Questions via Phrasal Semantic Parsing. Natural Language Processing and Chinese Computing, vol. 496, Dec 2014, pp. 333-344.

P. Keyno, «MATI» — Russian State Technological University, Moscow, Russia, pavel@keyno.com A. Siluyanov, «MATI» — Russian State Technological University, Moscow, Russia, ctcmati@yandex.ru

Design and implementation of a declarative web-interface modeling language interpreter on a high-performance distributed systems

The article examines the development process of the BML interpreter and the high-performance cluster building with BML support. The language allows to modeling a web-interfaces and their business logic in a declarative form. The article contains the comparative analysis of some critical components in the system. In particularly there is a comparison of efficiency of the Web platforms in static and dynamic environments between CGI, FastCGI and traditional PHP programming. Efficiency of compiling and interpreting languages also considered. According to study, the FastCGI platform with the C++ language gives the best result of performance. Detailed architecture with the base system components is considered. The interpreter contains low-level programming elements and requires performing the following tasks: HTTP requests parsing, store and retrieve user sessions, interact with DBMS, parsing of XML-like documents, processing a regular expressions, provide the computed data to templates and etc. There are some resource-intensive processes in the interpreter and they are also requiring detailed analysis. The BML language based on XML syntax therefore its interpreter require a proper XML-parser. Authors chose libxml2 as the best way for the fast development although it shown not highest efficiency. Some of components are developed independently: HTTP-parser, configuration files parser, session manager, all interface classes and more. In the article presented the development process of the interpreter in high-performance systems as complex engineering solution. Keywords: Web, backend, server programming, highload systems, cloud computing, clusters, servers, interpreter, declarative programming, CGI, FastCGI, BML, BlockSet, HTML, XML, MVC, C++.

About authors:

P. Keyno, Lecturer, Department of System Modeling and Engineering Graphics A. Siluyanov, PhD in Technique, Associate Professor, Department of System Modeling and Engineering Graphics

For citation:

Keyno P. P, Siluyanov A. V. Design and implementation of a declarative web-interface modeling language interpreter on a high-perfomance distributed systems. Prikladnaya informatika — Journal of Applied Informatics, 2015, vol. 10, no. 1 (55), pp. 55—70.

i Надоели баннеры? Вы всегда можете отключить рекламу.