Хранение данных приложения
#
Васильев Андрей Михайлович, 2024
Версии презентации
Архитектура приложения
#
Жёлтым обозначены физические (виртуальные) машины, зелёным — составляющие
веб-приложения, синим — важные компоненты системы
- Веб-сервер обслуживает множество клиентов
- Клиентам необходимо множество документов, для получения которых выполняется
несколько HTTP-запросов
- HTML-документ с данными для отображения
- CSS-документы с описанием классов для стилизации HTML
- JS-документы для выполнения динамических действий на стороне клиента
- Для формирования документов серверу недостаточно данных, которые хранятся в
его оперативной памяти
- Необходимо обратиться к хранилищу данных (СУБД или другая система хранения) за
динамическими данными: список товаров, их количество, данные пользователя
- Необходимо обратиться к внутренним ресурсам для получения статической
информации: CSS/JS-документы, шаблоны страниц
- Клиентам необходимо обратиться за документами, которые были загружены или
сформированы приложением: изображения, архивы, PDF-документы
Максимальное использование локальных ресурсов
#

- Современные системы предоставляют множество процессоров, способных независимо
друг от друга обрабатывать данные
- HTTP-запросы легко обрабатывать на нескольких потоках, т.к. каждый запрос не
зависит от других запросов
- HTTP-сервера обычно запускают множество процессов (и потоков), которые
используют разные процессоры
- Потоки имеют доступ к общим данным:
- Файловая система
- Ресурсы приложения
- Данные в оперативной памяти
- Для изменяемых данных необходимо аккуратно подходить к задаче редактирования
общих данных: данные в оперативной памяти и на файловой системе
- Библиотека http4k по умолчанию запускает несколько процессов
Балансировка запросов между компьютерами
#

- Для обработки большого числа запросов от клиентов мощностей одного компьютера может не хватать
- Можно организовать обработку запросов с помощью множества одинаковых приложений, запущенных на нескольких компьютерах
- Выводы из данной архитектуры:
- Файловая система не может служить подходящим средством для хранения общих бинарных данных
- Все данные приложения должны находится в единых системах хранения: кластере СУБД-серверов, серверах хранения больших данных и т.д.
- Приложение должно считывать конфигурацию из сетевой службы.
- Невозможно организовать доступ к общим данным в оперативной памяти, необходимо использовать специализированные инструменты
- При разработке локального приложения стоит изначально рассматривать сложности перехода к запуску нескольких приложений на нескольких серверах
Локальные данные приложения
#
Рассмотрим следующие источники данных, доступные JVM-приложениям:
- Ресурсы приложения
- Файловая система
Общие свойства
#
- Предоставляют данные в виде файлов
- Предоставляют данные в иерархической структуре каталогов
- Для построения путей к файлам можно использовать абсолютные и
относительные пути
Отличия
#
- Данные внутри ресурсов доступны только на чтение
- Ресурсы поставляются вместе с исполняемым кодом приложения
- Файлы поставляются отдельно
- Абсолютные пути внутри ресурсов будут работать на любом
компьютере для файлов стоит использовать относительные
Работа с данными без СУБД
#
СУБД решает много вопросов разработки веб-приложений: проблемы надёжного
хранения данных, проблемы совместного доступа, проблемы управления большим
объёмом данных
Без СУБД будем считывать и записывать все данные приложения с файловой системы
- При старте приложение считывает информацию из файловой системы
- Во время работы приложение изменяет данные в оперативной памяти
- При завершении работы приложение сохраняет данные на файловую систему
Ключевые проблемы:
- Возникновение коллизий в данных в оперативной памяти в случае редактирования в
нескольких потоках
- Надёжное сохранение данных в случае завершения работы приложения (приложению
могут не дать корректно завершить работу)
Жизненный цикл JVM-приложения
#
- Создаётся процесс внутри операционной системы, в рамках которой работает
первый JVM-процесс
- Запускается функция main(), порождающая множество JVM-процессов
- По завершении работы последнего JVM-процесса выполняется вызов обработчиков
завершения работы
- После выполнения всех задач по обработке запроса основной процесс ОС
завершает свою работу
Жизненный цикл http4k-приложения
#
- Функция start() создаёт столько JVM-процессов, сколько есть процессоров в
системе
- Во время инициализации приложения функции по созданию фильтров вызываются 1
раз на каждый процессор
- Есть функция stop(), которая завершит работу всех потоков
Написание обработчика завершения работы приложения
#
public void addShutdownHook(Thread hook)
Обработчик завершения работы JVM-приложения — это объект, реализующий интерфейс
Thread, который описывает отдельный поток выполнения
Kotlin предоставляет удобную функцию для создания объектов, реализующих поток:
fun thread(
start: Boolean = true,
...
block: () -> Unit
): Thread
- Аргумент
start
указывает надо ли сразу запускать данный поток на исполнение
- Аргумент
block
содержит код, который надо выполнять в рамках потока
Обработчики остановки приложения не должны запускаться в момент создания, а в
блоке кода должна находиться логика по сохранению данных
Это должно позволить приложению сохранять данные, которые пользователь ввёл за
время работы с приложением
Ручная корректная остановка работы приложения
#
Ввиду того, что обработчик завершения JVM-процесса может не всегда сработать
(например при остановке приложения из IDEA в Windows), можно реализовать
остановку приложения по отправке команды из командного интерфейса
- При старте приложения выполняется считывание данных в оперативную память
- Выполняется создание обработчиков HTTP-запроса
- Создание обработчика остановки JVM-процесса, чтобы можно было обработать
остановку JVM-процесса
- Запуск HTTP-сервера и всех процессов-обработчиков
- Блокировка основного потока приложения на считывание данных из стандартного
потока ввода
- Остановка сервера (данный шаг выполнится, если пользователь ввёл данные и
нажал Enter)
- Автоматическое выполнение обработчика остановки приложения
Такое приложение также корректно будет обрабатывать сигнал остановки