При работе с HTTP-сервисами в файловой информационной базе 1С часто возникает ситуация, когда при одновременной отправке нескольких запросов они выполняются не параллельно, а друг за другом. Это приводит к значительным задержкам и может полностью остановить обмен данными, если один из запросов окажется "долгим". Давайте вместе проанализируем ситуацию, выясним причину такого поведения и разберем конкретные способы решения этой проблемы.
Основная причина кроется в архитектурной особенности работы веб-сервера (например, Apache) с файловой базой 1С. Модуль расширения веб-сервера, который обеспечивает связь с файлом базы данных (.1CD), работает в строго однопоточном режиме. Это официальная информация от 1С. На практике это означает, что все поступающие HTTP-запросы от внешних систем выстраиваются в единую очередь и обрабатываются последовательно, один за другим. Пока не завершится обработка текущего запроса, следующий не будет взят в работу, даже если он очень простой и быстрый.
Теперь, когда мы понимаем корень проблемы, рассмотрим несколько подходов к ее решению, от простого архитектурного до более сложного инфраструктурного.
Этот метод не устраняет однопоточность, но позволяет значительно снизить ее негативное влияние. Идея заключается в том, чтобы максимально ускорить работу самого HTTP-метода, перенеся всю "тяжелую" логику в фоновый процесс.
Разберем по шагам, как это реализовать:
Создаем буферное хранилище. В конфигурации создадим объект для временного хранения входящих запросов. Идеально для этой цели подходит РегистрСведений, назовем его, например, ОчередьВходящихHttpЗапросов. У него могут быть ресурсы для хранения тела запроса (строка неограниченной длины), его заголовков, даты получения и статус обработки.
Модифицируем HTTP-метод. Основная задача HTTP-метода теперь — не обработать запрос, а как можно быстрее его принять, сохранить и отдать ответ "OK". Вся работа метода сводится к нескольким простым действиям: получить данные запроса и записать их одной транзакцией в наш регистр сведений.
Создаем обработчик очереди. Настраиваем РегламентноеЗадание, которое будет запускаться с определенной периодичностью (например, раз в минуту). Этот фоновый процесс будет выбирать из нашего регистра сведений необработанные записи, выполнять всю сложную логику (создание документов, расчеты, запись в другие регистры) и помечать записи как обработанные.
Посмотрим на пример кода для HTTP-метода. Его логика становится предельно простой:
Функция ОбработатьЗапрос(Запрос)
// Получаем тело запроса, например, в формате JSON
ТелоЗапросаJSON = Запрос.ПолучитьТелоКакСтроку();
// Быстро записываем данные в наш буферный регистр
НаборЗаписей = РегистрыСведений.ОчередьВходящихHttpЗапросов.СоздатьНаборЗаписей();
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.ДатаПолучения = ТекущаяДата();
НоваяЗапись.ТелоЗапроса = ТелоЗапросаJSON;
НоваяЗапись.Статус = Перечисления.СтатусыОбработкиЗапросов.Новый;
Попытка
НаборЗаписей.Записать();
Исключение
// Здесь можно добавить логирование ошибки записи
// и вернуть ответ с ошибкой
Возврат Новый HTTPОтвет(500);
КонецПопытки;
// Сразу же возвращаем успешный ответ, не дожидаясь реальной обработки
Возврат Новый HTTPОтвет(200);
КонецФункции
Преимущество этого подхода: время блокировки единственного потока обработки сокращается до минимума — времени, необходимого для одной записи в регистр. Это позволяет системе принимать большое количество запросов практически одновременно, не создавая "пробку".
Это более сложный, инфраструктурный подход, который позволяет добиться реальной параллельной обработки запросов. Он основан на том, что ограничение однопоточности действует в рамках одного процесса веб-сервера. Если мы запустим несколько таких процессов, каждый из них сможет обрабатывать свой запрос параллельно с другими.
Рассмотрим подробнее, как выстроить такую архитектуру:
Публикация нескольких экземпляров. Для одной и той же файловой базы данных (.1CD) необходимо опубликовать на веб-сервере несколько сервисов. Каждый экземпляр Apache (или IIS) должен работать на своем собственном, уникальном порту. Например, первая публикация на порту 8081, вторая на 8082, третья на 8083 и так далее. Каждый такой экземпляр будет являться отдельным рабочим процессом.
Настройка обратного прокси-сервера (Reverse Proxy). Перед нашими экземплярами Apache устанавливается балансировщик нагрузки. Отличным решением для этой задачи является nginx. Он будет служить единой точкой входа для всех внешних систем (например, принимать запросы на стандартный порт 80 или 443).
Балансировка нагрузки. Nginx настраивается таким образом, чтобы распределять входящие запросы по пулу наших работающих экземпляров Apache (на портах 8081, 8082, 8083). Когда приходит первый запрос, nginx отправляет его на первый сервер, второй запрос — на второй, и так далее по кругу или по другому алгоритму.
Таким образом, мы получаем псевдо-многопоточность: хотя каждый процесс веб-сервера по-прежнему обрабатывает запросы к файловой базе последовательно, у нас есть несколько таких процессов, работающих параллельно.
Важный момент: при настройке балансировки в nginx часто используют директиву ip_hash. Она гарантирует, что все запросы с одного и того же IP-адреса будут всегда попадать на один и тот же экземпляр Apache. Это может быть критично для поддержания сессии пользователя или для операций, требующих последовательного выполнения от одного клиента.
В заключение отметим, что файловая база данных не предназначена для высоких нагрузок и параллельной работы. Если вам требуется стабильная и производительная система для обработки множества одновременных запросов, наиболее правильным решением будет переход на клиент-серверный вариант работы 1С. Однако, если такой возможности нет, описанные выше методы помогут значительно улучшить отзывчивость ваших HTTP-сервисов.
← К списку