Диплом: Повышение производительности веб-приложения за счет обратного проксирования с помощью NGINX

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам
22
главах. Как было отмечено, Nginx легко справляется с отдачей статических
файлов. Во второй главе работы будет произведена настройка
многоуровневого кэша, который полностью решит проблемы с отдачей.
1.3.2. Одинаковое содержимое страниц
Для того чтобы кэш работал эффективно, нужно стремиться к
выполнению двух условий:
1) Страница должна всегда браться из кэша, если она не менялась с
предыдущего обращения
2) Пользователи должны разделять кэш, то есть если разные
пользователи видят страницу одинаково, это должна быть одна
страница в кэше, возвращенная одним запросом к бек-энду
Если эти условия выполнены полностью, то это очень хорошо. Nginx
предоставляет средства для их выполнения, но они применимы не во всех
ситуациях. Директива proxy_cache_valid позволяет проверять через заданные
промежутки времени изменения содержимого[36,37]. Если страница не
менялась, бекэнд отправляет ответ 304 (Not Modified) и страница продолжает
оставаться в кэше. Это приемлемо для, например, статьи, но не может
использоваться для страницы с сообщениями пользователей (она должна
обновляться у всех после добавления сообщений кем-либо, а не время от
времени). Такое кэширование будет применено для статических страниц с
документацией в исследуемом приложении и подробно рассмотрено в главе
2.
Возвращать пользователям одну страницу приемлемо, если она не
содержит персонифицированной информации. Соответственно, если на
странице в шапке отображается логин пользователя, не смотря на то, что тело
страницы может быть для всех одинаково, возвращать ее из кэша всем
пользователям нельзя.
Первая проблема решается с помощью использования специального
модуля ngx_http_cache_purge_module или возможностей управления кэшем,
23
предоставляемых коммерческой редакцией Nginx Plus. С помощью
определенного запроса можно сообщить серверу немедленно уничтожить
страницу в кэше и она будет получена заново[12,7]. Об этих возможностях
речь пойдет в главе 3.
Вторая сложность может решаться с помощью технологии ssi Server
Side Inclusion (включение на стороне сервера). SSI это именованные блоки,
описанные разметкой html, в которые прокси получает содержимое во время
выполнения запроса. Nginx имеет возможность работать с SSI-блоками.
Соответственно, прокси может получать с бек-энда основную страницу с
персонифицированной информацией и с помощью подзапросов получать
блоки SSI, которые могут кэшироваться отдельно.
В случае приложения, рассматриваемого в работе, есть возможность
использовать SSI, но для этого требуется внесение изменений в приложение.
Возможность подобных изменений и возможности, которые они дадут, будут
более подробно рассмотрены в главе 3.
1.3.3. Повышение отказоустойчивости
Порой очень важно обеспечить отказоустойчивость своего
приложения. Как было отмечено ранее, Nginx дает возможность создавать
кластеры для серверов бек-энда, а Docker дает возможность развернуть
кластер, сделав сам nginx отказоустойчивым[12].
Для приложения, рассматриваемого в работе, отказоустойчивость
важна, так как с ним в любое время суток могут работать удаленные
сотрудники и клиенты организации.
Одной из предпосылок к созданию кластера из серверов бек-энад
послужила ситуация, в которой на время планового обслуживания сервер
становится недоступен на некоторое время. Не смотря на то, что
обслуживание проводится в ночные часы, некоторые сотрудники из других
часовых поясов стали сообщать, что именно в это время им необходимо было
24
выполнять какие-то работы и им пришлось ждать завершения операций
обслуживания чтобы зайти в систему.
Несколько бек-энд серверов, отключающихся в разное время суток,
полностью решают эту проблему. К тому же выход из строя одного из них по
иным причинам ни как не влияет на работу всего приложения. Благодаря
использованию разделяемого хранилища сеансовых данных, пользователям,
запросы которых обслуживались вышедшим из строя сервером, даже не
придется заново входить в систему.
25
ГЛАВА 2. Внедрение обратного прокси-сервера на базе NGINX
2.1. Цели существования оптимизируемого приложения и
задачи, решаемые им
2.1.1 Приложение RMS
Веб-приложение, являющееся объектом в данной работе, представляет
собой php приложение, работающее под управлением веб-сервера Apache и
предназначенное для взаимодействия сотрудников организации с клиентами
и друг с другом. RMS это англоязычная аббревиатура, означающая
«requirements management system» (система управления требованиями).
Приложение используется фирмой, специализирующейся на разработке
решений для 1С.
Объектами, с которыми ведется работа в системе, являются задачи.
Они могут быть подчинены друг другу и ссылаться друг на друга, образуя
достаточно сложную структуру. Объединяются задачи по двум свойствам –
принадлежность контрагенту и принадлежность проекту контрагента. При
этом контрагент – родительская сущность для всего, что может происходить
в системе, а проект – скорее, группа, объединяющая задачи и используемая
для назначения пользователям с ограниченными правами и различных
разрешений и прав доступа.
Пользователи регистрируются в системе, после чего управляющий
назначает им роли – контактное лицо контрагента, сотрудник, руководитель
проектов, помощник управляющего или управляющий. Роль определяет
уровни доступа пользователя к проектам и задачам в них.
Работа в приложении осуществляется следующим образом:
- контактное лицо контрагента формирует требование и пишет его в
соответствующей задаче для новых требований, либо отправляет
электронным письмом на специальный адрес;
- сотрудник, следящий за появлением новых требований в системе,
создает на его основании задачу анализа требования;
26
- дальнейшая переписка, необходимая для уточнения деталей или для
сдачи результата ведется в созданной задаче
- после достижения результата, необходимого заказчику, задача
закрывается.
Это основной процесс, который повторяется снова и снова по мере
работы с контрагентами. Для достижения максимальной производительности
труда необходимо, чтобы отображение списков задач и содержимого задачи
происходило максимально быстро и не осложняло работу пользователям.
Также приложение RMS тесно интегрировано с системой управления
версиями CVS, которая используется для хранения результатов разработки.
Разрешения на коммиты, установка очереди на коммит и другие действия
выполняются через веб-приложение. Конкретно эта часть системы работает
хорошо и в работе рассматриваться подробно не будет, просто следует
отметить, что она есть.
Цель, которая преследуется в работе – не внося изменений в
приложение повысить производительность внешними средствами. Это
решено сделать с помощью кэширующего сервера, как говорилось ранее. В
следующем разделе подробнее рассмотрены особенности динамических
страниц с содержимым задач и списками.
2.1.2. Особенности динамического содержимого
Условно, приложение генерирует несколько видов динамических
страниц:
1. Задачи – это сообщения, которые пользователи написали друг другу.
Если сотрудник имеет доступ к задаче, он видит все сообщения,
которые контактные лица контрагента и сотрудники организации
писали в ней. Если контактное лицо контрагента имеет доступ к
задаче, оно видит все сообщения, просмотр которых разрешен
контактным лицам. То есть, теоретически, можно кэшировать
27
сообщения в задаче и, пока ни кто не написал в нее, отдавать одну
версию всем сотрудникам, а другую – контрагенту.
2. Списки задач, в которых перечислены задачи, доступные
пользователю. Эти списки разные у сотрудников, кроме
управляющих и помощников управляющих – они видят все задачи в
системе. Можно было бы смело отдавать управляющим из кэша
общий список.
3. Различные отчеты, которые строят управляющие – эти страницы
быстро теряют актуальность и нужны всего нескольким
сотрудникам. С учетом решения выделить для приложения
несколько бек-эндов, возможности сохранять отчеты и того, что они
строятся не часто, эти страницы будут просто строиться заново
каждый раз.
Но есть обстоятельство, не позволяющее использовать общий кэш для
любой из приведенных сущностей без внесения изменений в приложение.
Перед каждой задачей в списке находятся цифры, означающие количество
сообщений, не просмотренных сотрудником. Цифра уникальна для каждого
из пользователей. Также и в задаче – на фоне абсолютно идентичного
содержимого сообщения, которые пользователь не видел ранее, помечаются
как новые. Существуют технологии, позволяющие избавиться от этого,
например, отдавать пользователю страницу со скриптом, который после ее
загрузки будет получать все эти метки[42]. Разделяемый между
пользователями кэш сильно уменьшил бы нагрузку на бек-энд и увеличил бы
скорость, но внесение подобных изменений противоречит условию «не
вносить изменений в приложение», поэтому все же страницы будут
кэшироваться индивидуально. Если модифицировать приложение,
необходимо будет получать с сервера сперва основное содержимое, а затем с
помощью дополнительного ajax запроса загружать на сформированную
страницу уникальные для пользователя блоки[42] (например, упомянутые
выше цифры).
28
2.1.3. Статические файлы
В системе используются статические файлы, представляющие собой
различные скрипты, стили, изображения и страницы с документацией.
Кэширование содержимого такого вида делается достаточно просто и
работает эффективно. Далее в работе будет рассмотрен конфигурационный
файл nginx и будет продемонстрировано, как там осуществляется
кэширование статики.
Отдельного упоминания заслуживает статика, отдаваемая по запросу
GET к скрипту index.php. В основном это относится к изображениям,
прикрепленным к сообщениям в задачах. Это сделано для того, чтобы при
просмотре изображений пользователь не уходил со страницы, на которой
находится, а смотрел изображение с помощью удобного средства для
просмотра на JavaScript.
2.2. Установка и настройка кэширующего прокси-сервера
NGINX
2.2.1. Установка контейнерного приложения
Изначально было решено использовать Docker для запуска прокси-
сервера и приложения. Помимо того, что использование Docker давно уже
считается стандартом, имеется контейнерная версия приложения RMS,
подготовленная разработчиком несколько месяцев назад. Изначально стек
приложения включает в себя три контейнера – web, db и cvs. Система
управления версиями остается в прежнем месте, поэтому контейнер cvs был
исключен, вместо него добавлен контейнер nginx. Для оркестрации
контейнеров описанного стека используется упомянутый в первой главе
Docker Compose.
Структура каталога с приложением на сервере Docker весьма объемна и
полностью приведена в приложении 3.
29
Файл docker-compose.yml приведен полностью в приложении 1. В нем
можно увидеть, что используется еще несколько дополнительных томов и
файлов настроек.
Существует специальное контейнерное приложение docker-compose-viz
от PMSIpilot, которое позволяет визуализировать структуру стека
приложения. Схему со структурой приложения в формате png можно
получить, если в консоли на машине, где в данный момент находятся образы
контейнеров с приложением, из каталога в котором находится файл docker-
compose.yml, выполнить команду:
sudo docker container run --rm --name dcv -it -v $(pwd):/input
pmsipilot/docker-compose-viz render -m image docker-compose.yml [13]
Рисунок 1. Структура стека контейнеров приложения RMS.
Порты 8888, 3308 и 8088 необходимы на время отладки и анализа
работы приложения и не доступны из вне локальной сети.
Как можно заметить, Nginx непосредственно не связан с контейнерами
приложения – он вообще находится в сети хоста docker. Это сделано
временно для простого решения, чтобы не делать прокси прозрачным, при
этом обеспечив получение серверами бек-энда (контейнер web и сервер srv
старый сервер с приложением) запросов с одинакового IP адреса. В
противном случае серверу srv будут приходить запросы от сервера локальной
сети, а в контейнер web – из внутренней сети docker.
30
К серверу баз данных, роль которого выполняет контейнер db,
подключены тома с базой данных и файл конфигурации. К контейнеру с
приложением в качестве томов также подключены файлы приложения и
конфигурации. К Nginx подключен именованный том для хранения кэша и
логов (хотя Docker имеет удобную и мощную подсистему для работы с
логами, в данном случае было принято решение собирать отдельные файлы,
хранящиеся на томе).
Далее необходимо убедиться, что текущим каталогом является каталог
с приложением и выполнить команду:
sudo docker-compose up
После этого приложение будет запущено, а его статус можно увидеть с
помощью команды docker-compose ps:
Рисунок 2. Статус запущенного стека приложения.
В итоге имеется запущенное контейнерное приложение, способное
принимать клиентские подключения на 443. Далее необходимо подготовить
базу данных для работы.
2.2.2. Подготовка приложения
Основной составляющей приложения является база данных. В качестве
СУБД приложение использует MySQL 5.7. На данный момент имеется
контейнер db с пустым кластером. Необходимо создать базу данных для
приложения, заполнить ее актуальными данными и настроить репликацию
master-slave между старым сервером и контейнером. Контейнер с
приложением будет обрабатывать только запросы GET, направляемые на
31
него силами nginx. Писать данные можно будет по прежнему только на
старом сервере.
Для начала необходимо подготовить конфигурационные файлы на
ведущем (master) и ведомом (slave) серверах[1,20]. На ведущем, старом,
сервере приложения в файл my.cnf нужно добавить следующие строки:
server-id = 2
log-bin=/var/db/mysql/RMS-mysql-bin
log_bin_trust_function_creators = 1;
Эти директивы назначают серверу идентификатор и указывают путь к
бинарному логу, в который записываются все изменения БД.
На новом, ведомом, сервере изменения в конфигурацию вносятся
путем редактирования файла conf/mysql-rms.cnf из каталога приложения,
который копируется в контейнер db при запуске:
server-id = 2
relay-log = /var/lib/mysql/mysql-relay-bin
log_bin = /var/db/mysql/RMS-mysql-bin
log_bin_trust_function_creators = 1
binlog_do_db = RMS
Эти директивы назначают идентификатор сервера и указывают путь к
бинарному логу на мастере.
На сервере с Docker в консоли из каталога с приложением нужно
выполнить команду sudo docker-compoer exec db /bin/bash, после этого
появится командная строка контейнера. В ней выполняются команды:
mysql -u root -p
CREATE DATABASE RMS;
exit
Создана пустая база данных RMS. С ней будет работать приложение,
оно уже сконфигурировано на ее использование.
Далее на старом сервере в консоли необходимо выполнить:
mysql -u root -p

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

«Психологическое сопровождение персонала в организации на примере ООО «Крокус»
Cовершенствование деловой оценки персонала в организации (на примере ООО "Даймонд кейтеринг развитие")
PR-коммуникации в сфере общественного питания (на примере кафе-кондитерской «Cream Cheese»)
SMM как средство повышения эффективности работы учреждений социокультурной сферы (на примере Малого театра)
Value-based education: ценности в системе образования и способы их реализации на уроке английского языка. Опыт Европейских стран
Work-life balance подход в управлении рабочим временем молодых сотрудников (на примере ООО «МГТ-сервис»)
Актуализация контента, отражающего концепцию «диалога культур», при освоении английского языка взрослыми обучающимися
Актуализация приемов инсценирования и драматизации в рамках интерактивной модели обучения английскому языку в старших классах
Актуальные подходы в построении внутреннего pr строительной компании (на примере ООО "Ренессанспроект")
Анализ деловой активности и экономической эффективности деятельности организации (на примере АО «СГ-Транс»)