Scientific journal
Modern high technologies
ISSN 1812-7320
"Перечень" ВАК
ИФ РИНЦ = 0,940

MATHEMATICAL MODEL AND HYBRID ARCHITECTURE OF A CLIENT-SERVER APPLICATION WITH A SOFTWARE GATEWAY-ADAPTER

Alpatov A.N. 1 Studennikov M.R. 1
1 MIREA State University
2074 KB
The development of data networks and the introduction of the Internet protocol suite (TCP/IP), as well as a general increase in data transfer rates, led to the development of distributed systems, often implemented in the framework of three-tier client-server architectures. To organize the interaction between client and server software, a huge number of methods and approaches have been developed, which have been formalized in the form of appropriate technologies. This variety of used technologies imposes significant challenges in organizing the integration of software elements written in scripting languages such as Python, which support a huge stack of technologies for integration. To solve this problem, this paper proposes a way to implement an integration gateway based on a bundle of Ngnix middleware and Daphne with Gunicorn, to integrate WSGI and ASGI servers. Also the mathematical model of the developed system, taking into account the heterogeneity of requests, flowing in the system is given in the work. The mathematical description of the developed system, taking into account the formulated division of the system into the areas determined by the used program layers, which can be useful for client-server system management or development of load balancing mechanisms in distributed systems. To evaluate the properties of the developed system and to solve the problem of managing the system, we propose the joint use of the parameters introduced in this paper, the accuracy of object identification and the responsiveness index, as part of the calculation of the harmonic weighted average.
application programming interface
client-server application
weighted harmonic mean
asynchronous and synchronous communication
WSGI

В реалиях современного мира новые сайты в интернете появляются каждый день. Их разработке и разработке веб-приложений посвящена большая часть ИТ индустрии. Часто перед разработчиками ставятся задачи быстрой и бюджетной разработки веб-приложений. Для решениях таких задач хорошо подходит популярный веб-фреймворк Django [1], написанный на Python. К основным достоинствам Django относятся простота его использования, широкий инструментарий, включенный в него, открытость его исходного кода и наличие большого количества документации и статей о нем.

Одним из финальных этапов разработки веб-приложения является его развертывание на сервере. В случае Django-приложений есть несколько важных нюансов их развертки. Большинство веб-серверов не понимают язык Python, поэтому были разработаны два стандарта (интерфейса) WSGI и ASGI.

WSGI – основной стандарт Python, который поддерживает только синхронный код.

ASGI – относительно новый стандарт, который дает доступ к функциям параллельного выполнения кода: WebSocket, Server-Sent Events, HTTP/2 и др. ASGI является наследником WSGI и имеет с ним обратную совместимость.

Для развертывания WSGI-приложения часто используются связки, представленные на рис. 1.

missing image file

Рис. 1. Популярные схемы развертки WSGI-приложений

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

Связка с использованием промежуточного слоя определённого mod_wsgi, который в настоящее время является одним из популярнейших модулей-адаптеров WSGI Python, продолжительное время активно использовалась разработчиками распределённых систем [2]. Основным преимуществом mod_wsgi является простота развёртывания и его использования на практике, но в то же время главным недостатком mod_wsgi является то, что он может не поддерживаться крупными хостинг-провайдерами, и его можно использовать только с конкретным сервером приложений, а именно Apache. Такое обстоятельство может быть критичным для некоторых проектов.

uWSGI – это программная платформа, которая включает в себя как непосредственно сервер приложения, так и другие механизмы, такие как прокси-серверы, плагины запросов и т.д. [3]. Всё это достигается благодаря модульной конструкции системы. uWSGI был написан специально для Python, поэтому его легко установить через pip. Другими достоинствами данного сервера является то, что он обладает относительно низким порогом вхождения и позволяет создать ещё один промежуточный слой программного обеспечения, что делает возможным снять часть функционала непосредственно с сервера (однако из-за этого необходимо проксировать запросы). Другим несомненным преимуществом данной платформы можно считать, относительную простоту его настройки.

Gunicorn [4] – это HTTP-сервер Python WSGI, который очень похож на uWSGI. Gunicorn – это зрелый, полнофункциональный сервер и менеджер процессов. Достоинства и недостатки у него такие же, как у uWSGI, однако Gunicorn лучше справляется с высокими нагрузками [5], легче настраивается и требует меньше ресурсов [6].

По итогу видим, что популярность связки Nginx-Gunicorn вполне оправдана.

Для развертывания ASGI-приложения официальная документация Django советует использовать следующие ASGI сервера: Daphne, Hypercorn, Uvicorn.

Daphne – это сервер протоколов HTTP, HTTP2 и WebSocket для ASGI и ASGI-HTTP, который был разработан специально для Django Channels, поэтому он считается эталонным [7].

Uvicorn – это быстрый и легкий ASGI-сервер, использующий uvloop и httptools [8]. Uvicorn поддерживает HTTP/1.1 и WebSockets. Uvicorn включает рабочий класс Gunicorn, позволяющий запускать приложения ASGI со всеми преимуществами производительности Uvicorn, а также предоставляет вам полнофункциональное управление процессами Gunicorn. Это позволяет увеличить или уменьшить количество рабочих процессов на лету, плавно перезапускать рабочие процессы или выполнять обновление сервера без простоев.

Hypercorn – это веб-сервер ASGI, основанный на библиотеках sans-io hyper, h11, h2 и wsproto и вдохновленный Gunicorn. Hypercorn поддерживает спецификации HTTP/1, HTTP/2, WebSockets (через HTTP/1 и HTTP/2), ASGI/2 и ASGI/3. Hypercorn может использовать типы рабочих asyncio, uvloop или trio [9].

Использование того или иного сервера для ASGI, помимо их характеристик, обуславливается и тем, какой фреймворк (Django Channels, Quart, FastAPI, BlackSheep) будет привносить асинхронность в проект. Так как в этой статье мы говорим о Django, то будем рассматривать преимущественно Django Channels.

Библиотека Django Channels [10] появилась недавно, около 4–5 лет назад. Эта библиотека привнесла в Django асинхронное сетевое программирование. Channels расширяет инструментарий Django и дает возможность работать не только с HTTP протоколом, но и с WebSocket (ws), протоколом чата, IoT-протоколом и другими. Django Channels использует ASGI интерфейс.

При разработке реальных проектов часто бывают ситуации, когда нужно в уже развёрнутый проект включить новые функции. К примеру, в готовое Django-WSGI-приложение необходимо включить Dajngo Channels, которые привносят вместе с собой ASGI. Для подобной ситуации в данной статье предложена конфигурация развертки веб-приложения, которую можно считать эталонной для перехода от WSGI к ASGI в рамках Django-приложений, использующих Django Channels.

Материалы и методы исследования

Рассмотрим случай, когда имеется рабочее развернутое Django-WSGI-приложение, работающее на популярной связке, показанной на рис. 2.

missing image file

Рис. 2. Текущая архитектура сервера

missing image file

Рис. 3. Файл конфигурации Nginx и сервис для Gunicorn

Nginx тут используется как обратный прокси-сервер, а также отвечает за выдачу статического контента. Gunicorn является прослойкой между Nginx и Django. HTTP запросы Nginx передает Gunicorn, который передает их уже в Django, который взаимодействует со слоем базы данных. Возможная конфигурация Nginx и Gunicorn представлена на рис. 3.

Если добавить в приложение Django Channels с каким-либо функционалом и попытаться проверить работу системы в данной конфигурации можно увидеть, что не работают лишь функции, которые используют WebSocket. Это происходит, во-первых, потому, что в конфигурации Nginx не указано, куда отправлять ws/ запросы, во-вторых, если бы мы направили их на Gunicorn, то вероятно получили бы ошибку, так как Gunicorn – HTTP-сервер. Функции же, которые не используют асинхронность, то есть которые работали в WSGI приложении, работают так, как ASGI имеет обратную совместимость.

После установки Daphne настраиваем Nginx и Daphne, как показано на рис. 4, 5.

missing image file

Рис. 4. Файл конфигурации Nginx

missing image file

Рис. 5. Файл сокет и файл сервис для Daphne

missing image file

Рис. 6. Гибридная архитектура клиент-серверного приложения со шлюзом-адаптером

Таким образом, получаем видоизменённую гибридную архитектуру, представленную на рис. 6.

В представленной выше архитектуре Nginx не только является обратным прокси-сервером, который отвечает за статический контент, но еще и является балансировщиком нагрузки, отправляя HTTP запросы на Gunicorn, а WS запросы – на Daphne. При такой конфигурации происходит выгодное распределение нагрузки. Так как Daphne способен обрабатывать HTTP запросы, можно впоследствии улучшить архитектуру, сделав Daphne резервным сервером для HTTP.

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

Если в аналогичной ситуации, когда нужно перевести свое приложение с WSGI на ASGI при уже развернутом Nginx+Gunicorn, и это необходимо сделать быстро и не потеряв в производительности, то вместо Daphne можно использовать Uvicorn. В описанной ситуации основным плюсом использования Uvicorn является то, что его настройка очень похожа на настройку Gunicorn. Хотя Uvicorn больше подходит для использования с FastAPI и имеет меньший функционал.

Модель обработки запросов в многоуровневых клиент-серверных системах

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

1. Пользователь – это актор, который хочет получить данные либо доступ к функциональности удалённого объекта.

2. Клиент-потребитель – это актор, через который пользователь осуществляет авторизированный доступ к удалённому поставщику сервиса.

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

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

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

missing image file, (1)

где missing image file – множество пользователей распределённой программной системы;

missing image file – множество гетерогенных акторов клиентов – потребителей распределённой программной системы;

θ – множество всех запросов в системе;

missing image file – множество поставщиков сервиса;

missing image file – множество представлений ресурса r.

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

missing image file, (2)

где missing image file – запросы типа WebSocket, сгенерированные парой missing image file;

missing image file – запросы типа http, сгенерированные парой missing image file.

Исходя из (2), общее количество запросов в системе в момент времени t определяется как

missing image file, (3)

где missing image file – i-й запрос актора типа WebSocket;

missing image file – i-й запрос актора типа HTTP.

Введём понятие пороговый барьер Ψκ, который будет определяться как программный слой, в рамках многослойной архитектуры, осуществляющий процесс маршрутизации поступающих запросов в систему. В современных системах пороговый барьер может быть определён через архитектурный паттерн Gateway [11]. Пороговый барьер определяет область σbarrier. Область, определяемую программными слоями перед пороговым барьером, будем называть предпороговой областью σfront барьера Ψκ. Область, определяемую промежуточным программным обеспечением, находящимся за барьером Ψκ, будем называть областью σback за пороговым барьером. Такое разделение оправдано тем, что в каждой из этих областей слой программного обеспечения, реализованный посредством использования современных фреймворков, может кешировать запросы, предобрабатывать, формировать цепочки обработки, обрабатывать как синхронно, так и асинхронно, а в некоторых случаях даже отклонять соответствующие типы запросов от их дальнейшей обработки [12]. Процесс обработки запросов всех типов в системе будет определяться как

missing image file, (4)

где S – конечное множество объектов ответа защищенного ресурса r из всего множества представлений Ri.

Отношение между множествами missing image file определено через биективное соотношение, что означает, что между множествами определено однозначное соотношение и, следовательно, missing image file.

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

missing image file, (5)

где +missing image file – однозначно определённые запросы типа missing image file предпороговой, пороговой и запороговой барьерных областей,

missing image file – однозначно определённые запросы типа missing image file предпороговой, пороговой и запороговой барьерных областей,

Q – общее число запросов в системе.

Следовательно, исходя из формулы (5), математическая интерпретация задачи идентификации запросов в системе может быть определена как соотношение

missing image file (6)

где missing image file – параметр оптимизации, определённый как общее количество однозначно определённых запросов, j-й пары missing image file.

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

missing image file (7)

где Si – общее число запросов для извлечения i-го ресурса.

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

missing image file, (8)

где missing image file – частота удовлетворения потребности пользователя в ресурсе r за один запрос из пары missing image file,

missing image file – частота удовлетворения потребности пользователя в ресурсе r за несколько запросов из пары missing image file.

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

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

missing image file, (9)

где missing image file – установленное значение индекса отзывчивости системы,

missing image file – действительное значение индекса отзывчивости системы.

Для процесса управления разработанной системы важно определить сбалансированность между двумя отслеживаемыми параметрами, введёнными нами ранее, а именно, между точностью идентификации объектов и индексом отзывчивости. Для решения данной задачи можно использовать метод среднего гармонического взвешенного [13, 14], который определяется следующим образом. Пусть имеется массив вещественных чисел missing image file, определённый значениями точности идентификации объектов, и массив вещественных чисел missing image file, сформированный из значений отзывчивости системы, тогда среднее гармоническое взвешенное может быть рассчитано как

missing image file (10)

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

missing image file, (11)

где γi – коэффициент баланса i-го класса (можно отождествить с вероятностью выбора соответствующего класса),

Hi – значение среднего гармонического взвешенного соответствующего класса,

n – общее количество классов.

Так как в рамках нашей задачи выделены 2 класса (n = 2), то модернизированная оценка взвешенного гармонического среднего для данного случая будет определена как

missing image file

missing image file (12)

Такой подход позволяет посредством установки значения параметров γ1 и γ2 балансировать между точностью идентификации объектов и индексом отзывчивости. Так, например, установка missing image file говорит о сбалансированном весе между точностью идентификации объектов и индексом отзывчивости системы.

Заключение

В данной работе предложен способ создания программных шлюзов для интеграции гетерогенных серверов в рамках клиент-серверного взаимодействия, который основан на использовании распространённых программных компонентов, что упрощает процесс внедрения предложенной системы в существующие проекты, которые написаны с использованием языка программирования Python и фреймворка Django. Предложенный способ даёт возможность интеграции серверов в рамках программного шлюза, основная задача которого заключается в ретрансляции запросов клиентского приложения во внешние удалённые серверы, которые могут быть связаны с программным шлюзом посредством WebSocket и HTTP. Это стало возможным благодаря внедрению и использованию django channels. Такой подход позволяет в существующие Django проекты внедрять как WebSocket клиентов, так и HTTP клиентов, а также даёт возможность обработки как синхронных, так и асинхронных функций, тем самым расширив возможности разработчиков клиентских приложений. Помимо этого, используемые программное обеспечение и библиотеки для формирования данного программного шлюза, а именно стек Ngnix+Gunicorn+Daphne, позволяют осуществить балансировку HTTP запросов клиентов, что, в свою очередь, позволит повысить скорость и стабильность всего клиент-серверного приложения. При таком конфигурировании системы Daphne будет являться резервным сервером/каналом, который может принимать проксированные Ngnix в случае неисправности Gunicorn или миграции со шлюзового протокола WSGI на ASGI. Предложенная математическая модель распределённой системы учитывает характер поступающих запросов, с возможностью тонкой настройки выделенных в данной работе параметров, что можно использовать при решении задачи управления вычислительной нагрузки [13] в рамках клиент-серверного приложения с многослойной архитектурой.