При создании веб-сервисов на платформе 1С:Предприятие разработчики часто сталкиваются со значительным падением производительности. Элементарный HTTP- или SOAP-сервис, возвращающий наименование товара по его коду, способно обрабатывать 100–150 запросов в секунду. Однако стоит добавить в алгоритм расчёт цены с учетом периодов, скидок или комиссий, как скорость обработки может упасть до 1–2 запросов в секунду. Разберём по шагам, почему возникает эта проблема и как оптимизировать работу веб-сервиса в 1С.
Проанализируем типовой сценарий работы веб-сервиса, который рассчитывает стоимость аренды или проживания для списка объектов за определенный период. В частых случаях код обработки вызова выглядит следующим образом:
Строка1 + Символ + Строка2 с явным приведением типов через Строка() или Формат().При таком подходе на каждый веб-запрос база данных получает десятки или сотни обращений (запросы в цикле), а процессор расходует время на динамическую компиляцию, приведение типов и создание строковых объектов в памяти. Если на веб-сервис поступает 100 параллельных вызовов в секунду, платформа 1С быстро исчерпывает рабочие потоки и ресурсы СУБД.
Рассмотрим, как правильно переписать алгоритм обработки, чтобы снизить нагрузку на платформу и СУБД.
1. Полное исключение запросов в цикле
Все необходимые данные для расчетов должны выбираться одним пакетом или единым запросом. Вычисления стоимости и начислений рекомендуется переносить непосредственно в язык запросов 1С, используя конструкцию ВЫБОР КОГДА ... ТОГДА и математические функции запроса.
2. Использование оптимизированной сериализации XML/JSON
Сложение строк через оператор + и приведение чисел к строке через Строка() работают медленно при больших объёмах данных. Для ускорения формирования ответа применяют специализированный объект ЗаписьXML и функцию XMLСтрока().
Рассмотрим пример правильного формирования текстового ответа от веб-сервиса:
// Создаем объект записи в память без использования вызовов Строка()
Запись = Новый ЗаписьXML;
Запись.УстановитьСтроку();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Наименование КАК Наименование,
| ЕСТЬNULL(Цены.Цена, 0) КАК БазоваяЦена,
| ВЫБОР
| КОГДА Номенклатура.СтавкаНДС = ЗНАЧЕНИЕ(Перечисление.СтавкиНДС.НДС18)
| ТОГДА ЕСТЬNULL(Цены.Цена, 0) * 18 / 118
| ИНАЧЕ 0
| КОНЕЦ КАК СуммаНДС
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ) КАК Цены
| ПО Цены.Номенклатура = Номенклатура.Ссылка
|ГДЕ
| Номенклатура.Ссылка В(&МассивСсылок)";
Запрос.УстановитьПараметр("Период", ТекущаяДата());
Запрос.УстановитьПараметр("МассивСсылок", МассивТоваров);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Используем ЗаписатьБезОбработки и XMLСтрока для максимальной скорости
Запись.ЗаписатьБезОбработки(Выборка.Наименование);
Запись.ЗаписатьБезОбработки("$");
Запись.ЗаписатьБезОбработки(XMLСтрока(Выборка.БазоваяЦена));
Запись.ЗаписатьБезОбработки("$");
Запись.ЗаписатьБезОбработки(XMLСтрока(Выборка.СуммаНДС));
Запись.ЗаписатьБезОбработки(Символы.ПС);
КонецЦикла;
РезультатТекст = Запись.Закрыть();
3. Денормализация и хранение готовых значений
Если алгоритм расчёта цен содержит сложную логику, вычислять её "на лету" при каждом обращении веб-клиента недопустимо. Если цены или скидки меняются не каждую секунду, необходимо рассчитывать их регламентными заданиями и записывать в промежуточные регистры сведений или плоские реквизиты. Получение уже готового значения из карточки или регистра по прямому индексу выполняется за считанные миллисекунды.
Разберём встроенные возможности платформы 1С:Предприятие 8.3 для работы с высокой нагрузкой.
1. Настройка пула сеансов (Session Reuse)
По умолчанию при каждом вызове веб-сервиса платформа может тратить время на инициализацию параметров сеанса и выполнение модуля сеанса (УстановкаПараметровСеанса). Чтобы исключить эти затраты, настраивается повторное использование сеансов:
Использовать.default.vrd на веб-сервере (Apache / IIS) настраиваются параметры пула:
reuseSessions="use", poolSize="10", poolTimeout="5".Благодаря этому веб-сервер удерживает готовые сеансы 1С открытыми и мгновенно передает поступающие запросы на исполнение без повторного входа в базу.
2. Модули повторного использования значений
Для условно-постоянных данных (курсы валют, коэффициенты сезонов, базовые матрицы тарифов) следует использовать общие модули с включенным свойством Повторное использование значений (На время сеанса или На время вызова). Кэшированные данные будут храниться в оперативной памяти рабочего процесса 1С (rphost) и отдаваться без единого обращения к СУБД.
Если потенциальная нагрузка на веб-сервис превышает сотни или тысячи запросов в секунду, стоит рассмотреть архитектурный подход выноса точек чтения за пределы 1С.
Cache-Control, ETag). Nginx будет отдавать готовые ответы из памяти за 1–2 мс, не нагружая сервер 1С.