При проектировании высоконагруженных сервисов, интеграций и систем фоновой обработки данных часто возникает необходимость передавать состояние или промежуточные таблицы между вызовами фоновых заданий. Рассмотрим подробно, с какими платформами ограничениями сталкивается разработчик и какие существоуют архитектурные варианты решения этой задачи без постоянной записи в базу данных СУБД.
Проанализируем базовую концепцию работы платформы 1С: каждый запуск регламентного или фонового задания происходит в отдельном изолированном сеансе. Кроме того, при работе в кластере серверов разные запуски заданий могут выполняться в различных рабочих процессах rphost. Из-за этого стандартные механизмы хранения контекста не работают так, как в обычном пользовательском сеансе:
ПараметрыСеанса невозможно.Разберем вариант, при котором задание не пересоздается платформой каждые несколько секунд, а работает непрерывно в одном долгоживущем сеансе.
Вместо частых запусков фонового задания по расписанию мы запускаем одно фоновое задание, внутри которого организуем бесконечный цикл. Пауза между итерациями задается с помощью системной процедуры Приостановить(), что предотвращает избыточную загрузку процессора.
Процедура ЗапуститьОбработкуВЦикле()
// Переменная сохраняет состояние между итерациями цикла
КонтекстСостояния = Новый Структура;
Пока Истина Цикл
// Выполняем полезную обработку
ОбработатьОчередь(КонтекстСостояния);
// Задержка выполнения на 5 секунд
Приостановить(5);
КонецЦикла;
КонецПроцедуры
Так как сеанс фонового задания не завершается, все промежуточные данные (таблицы значений, соответствия, структуры) бессрочно хранятся в оперативной памяти сервера.
Обеспечение отказоустойчивости: Для защиты от падения процесса создается отдельное регламентное задание-диспетчер. Оно запускается с редкой периодичностью (например, раз в 5 минут), проверяет состояние основного задания через менеджер ФоновыеЗадания и перезапускает его в случае аварийной остановки.
Если перезапуска фонового задания платформой избежать нельзя, но требуется полностью исключить нагрузку на физические накопители и СУБД, разберем работу с файловым кэшем в оперативной памяти.
На уровне операционной системы сервера монтируется диск в ОЗУ (tmpfs в Linux или RAM-диск в Windows). Фоновое задание сохраняет и считывает промежуточные данные с этого диска с помощью встроенных функций платформы.
// Сохранение промежуточного состояния во временный файл в ОЗУ
ЗначениеВФайл("/mnt/ramdisk/cache_data.dat", КонтекстСостояния);
// Чтение состояния при следующем запуске фонового задания
ФайлКэша = Новый Файл("/mnt/ramdisk/cache_data.dat");
Если ФайлКэша.Существует() Тогда
КонтекстСостояния = ЗначениеИзФайла("/mnt/ramdisk/cache_data.dat");
КонецЕсли;
Этот подход обеспечивает оперативное чтение и запись со скоростью работы оперативной памяти без задержек ввода-вывода I/O и нагрузки на базу данных.
Рассмотрим вариант с использованием стороннего хранилища данных в оперативной памяти. Данное решение выносит промежуточные данные за пределы процессов rphost 1С.
Серверный код фонового задания взаимодействует с внешним хранилищем Redis через HTTPСоединение (если у хранилища есть REST-интерфейс) или с помощью внешних компонент Native API. Это обеспечивает мгновенный доступ к общим данным из любых фоновых заданий и пользовательских сеансов.
Посмотрим на ещё один архитектурный подход: вся логика хранения состояния и обработки данных выносится во внешний сервисный процесс (микросервис). Фоновое задание 1С в этом случае выполняет лишь роль клиента, обращаясь к сервису по HTTP для передачи новых данных и получения результатов обработки.