Динамическое выполнение кода OneScript из 1С:Предприятие

В статье описан подход, позволяющий динамически выполнять фрагменты кода OneScript из 1С:Предприятие и получать результаты выполнения

Введение

Периодически возникают прикладные задачи, требующие от сервера приложений 1С:Предприятие больших вычислительных ресурсов, что приводит к необходимости установки дополнительных рабочих серверов на отдельном оборудовании и как следствие – к покупке дополнительных серверных лицензий.  Альтернативным путем, может являться выполнение “тяжелых” операций, на отдельном оборудовании в среде OneScript, с последующим возвратом результатов в 1С:Предприятие для дальнейшей обработки. Такой подход, позволяет сократить затраты на серверные лицензии 1С:Предприятие.

Реализация

В качестве основы, для нашего “сервера приложений” OneScript, используем каркасную конфигурацию для создания http-сервисов. При необходимости, мы можем развернуть ее на нескольких серверах и настроить NLB-кластер, что позволит увеличить суммарную производительность и обеспечит масштабируемость.

Поскольку  обратиться к “серверу приложений” можно только по протоколу http(s), все взаимодействие сводится к выполнению соответствующих http-запросов, с последующей обработкой полученных результатов. В качестве протокола, для передачи данных, между 1С:Предприятие и http-сервисами OneScript используем JSON. Данный формат достаточно прост в использовании и поддерживается штатными средствами 1С:Предприятие. Поскольку в OneScript 1.0.20, на базе которого создана каркасная конфигурация, не имеет штатной поддержки JSON, для сериализации и десериализации данных используем слегка модифицированные функции из этой публикации.  

На стороне 1С:Предприятие создадим функцию, которая отправляет POST запрос по указанному URL и передает в теле JSON объект, содержащий поля Параметры и Скрипт. Первое поле – содержит передаваемые параметры, а второе – собственно фрагмент кода, который необходимо выполнить. 

 
&НаКлиенте
Процедура ВыполнитьСкрипт(Команда)
// Вставить содержимое обработчика.
ДанныеТело = Новый Соответствие;
ДанныеТело.Вставить("Скрипт", Объект.Скрипт);
ДанныеПараметры = Новый Соответствие;

Для каждого Параметр Из Объект.Параметры Цикл
ДанныеПараметры.Вставить(Параметр.Имя, Параметр.Значение);
КонецЦикла;

ДанныеТело.Вставить("Параметры", ДанныеПараметры);
ЗаписьJSON = Новый ЗаписьJSON();
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеТело);
Объект.Результаты = ОтправитьЗапрос(Объект.URL, ЗаписьJSON.Закрыть());

КонецПроцедуры

&НаКлиенте
Функция ОтправитьЗапрос(Url, ТелоЗапроса = "") Экспорт

ЧастиUrl = ПолучитьЧастиURL(Url);

Запрос = Новый HTTPЗапрос();
Запрос.АдресРесурса = ЧастиUrl.ОтносительныйUrl;

Соединение = Новый HTTPСоединение(
ЧастиUrl.Сервер
, ЧастиUrl.Порт
,
,
,
,
,
);

Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "application/json");
Запрос.Заголовки = Заголовки;
Запрос.УстановитьТелоИзСтроки(ТелоЗапроса);
Ответ = Соединение.ОтправитьДляОбработки(Запрос);

Возврат Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);

КонецФункции // ОтправитьHTTPЗапрос()

 

На стороне OneScript, создадим http-сервис (в нашем примере – runscript.os), обработчик которого, получает переданный  объект JSON, и выполняет необходимый фрагмент кода.

 
Функция ОбработкаВызоваHTTPСервиса(Запрос) Экспорт

Ответ = Новый HTTPСервисОтвет(200);

Попытка

ДанныеЗапрос = JSON.Прочитать(Запрос.ПолучитьТелоКакСтроку());
Результат = Неопределено;
Параметры = ДанныеЗапрос["Параметры"];

Выполнить(ДанныеЗапрос["Скрипт"]);

ДанныеОтвет = Новый Соответствие;
ДанныеОтвет.Вставить("БылиОшибки", Ложь);
ДанныеОтвет.Вставить("Результат", Результат);

Исключение

Ошибка = ОписаниеОшибки();
ДанныеОтвет = Новый Соответствие;
ДанныеОтвет.Вставить("БылиОшибки", Истина);
ДанныеОтвет.Вставить("ОписаниеОшибки", Строка(Ошибка));

КонецПопытки;

Ответ.УстановитьТелоИзСтроки(JSON.Записать(ДанныеОтвет));
Возврат Ответ;

КонецФункции

 

Выполняемый фрагмент имеет доступ к переменной Параметры, которая представляет собой результат десериализации одноименного поля, передаваемого объекта JSON.

Возврат результатов, осуществляется присваиванием переменной Результат возвращаемого значения.

Возвращаемое значение, представляет собой объект JSON, который содержит информацию о наличии ошибок в процессе выполнения (поле БылиОшибки), а также информацию о возаращаемом значении (поле Результат), в случае успеха, или информацию об ошибке (поле ОписаниеОшибки), в случае ее возникновения. Данный объект может быть десериализован на стороне 1С:Предприятие для дальнейшего использования результатов выполнения.

Заключение

Вот таким вот нехитрым способом, практически за 10-15 минут, мы организовали динамическое выполнение фрагментов кода в среде OneScript.

Надеюсь, что данная статья поможет в создании нагруженных информационных систем, на основе платформы 1С:Предприятие.

19 Comments

  1. zeegin

    А как тут с безопасностью?

    Любой может исполнить произвольный код?

    Reply ↓
  2. blackhole321

    (1)Как таковые, http-сервисы OneScript, пока не предоставляют какого-либо функционала, связанного конкретно с безопасностью, однако Вы можете настроить безопасность на уровне web-сервера, в частности IIS имеет в этом плане богатые возможности, а также настроить ограничения на брандмауэре (Windows firewall with advanced features также имеет развитый функционал). Apache также имеет возможности по проверке подлинности и авторизации.

    Reply ↓
  3. 🅵🅾️🆇

    Эм, если у вас настолько тяжелые операции, что их надо выносить на отдельное оборудование и не годится кейс «выполнить регламентным заданием пока все спят» — зачем исполнять такие вещи с помощью jit языков, а не взять плюсы/раст/го?

    Reply ↓
  4. blackhole321

    (3)

    зачем исполнять такие вещи с помощью jit языков, а не взять плюсы/раст/го?

    Ну конечно можно и так, только в среднем, ситуация развивается постепенно, и к моменту, когда встанет вопрос о масштабировании, в системе уже будет приличное количество функционала, написанного на 1С. В предлагаемом Вами варианте, его надо будет полностью переписать на плюсах/расте/го, вместо переноса выполнения в среду OneScript, что потенциально более затратно. Соответственно и все люди, учавствующие в разработке и дальнейшей поддержке/доработке такого решения также должны будут владеть этим языком программирования.

    Reply ↓
  5. pallid

    наверное скоро начнут появляться вакансии, в которых будут требоваться 1Сники для инфроструктурных проектов ))))

    на чистом os немного тяжко поднимать http сервис, быстрей это сделать на os.web

    Reply ↓
  6. blackhole321

    (5)

    на чистом os немного тяжко поднимать http сервис, быстрей это сделать на os.web

    Ctrl+C -> Ctrl+V. Полагаю, что это не очень тяжко 🙂

    Reply ↓
  7. pallid

    (6) имел ввиду настройку https://infostart.ru/public/789679/ — как тут описано

    Reply ↓
  8. pallid

    (6)неговоря уже о невиндоус ОС

    Reply ↓
  9. blackhole321

    (7)Ну дык это же установка и настройка web-сервера, причем для разработки и отладки.

    Reply ↓
  10. blackhole321

    (8)В невиндоус — еще проще, пяток команд по моему и это тоже установка web-сервера.

    Reply ↓
  11. pallid

    (10) верю на слово, не пробовал )))) (т.е пробовал, но на 15 минут не смог победить, и забросил)

    просто в os.web это

    oscript.webhost.exe
    

    и все, и нет никаких настроек

    но там паттерн приложения mvc (тут могу быть проблемы у людей)

    Reply ↓
  12. blackhole321

    (11)Тут как-бы есть свои ньюансы 🙂

    просто в os.web это

    И это уже служба?

    Проверка подлинности, порты, доменные имена, url rewrite & reverse proxy etc.?

    Reply ↓
  13. pallid

    (12)

    И это уже служба?

    нет, не служба

    порт можно указать свой

    остальное i don`t kwon ))) не изучал, не требовалось

    но подозреваю что данную функциональность можно вынести вперед, до непосредственных сервисов.

    вот как раз и хочется понять чем выгодней использовать os против os.web, и делать все эти манипуляции

    Reply ↓
  14. blackhole321

    (13)

    нет, не служба

    Значит надо писать скрипт, запускающий при старте системы и в случае с Windows дать права на старт as batch job.

    Также наверное надо-бы установить .net core

    порт можно указать свой

    Порт я надеюсь не вшит в приложение и может быть сконфигурирован извне?

    но подозреваю что данную функциональность можно вынести вперед, до непосредственных сервисов

    Ну типа того. Так и поступают в продуктиве, интегрируют с IIS или Apache, ngix etc.

    Я собсно к тому, что .net core web application не заменяет web-сервер и его придется таки устанавливать и настраивать, кроме простых интранетных случаев.

    вот как раз и хочется понять чем выгодней использовать os против os.web, и делать все эти манипуляции

    Смотря для каких целей.

    Вы для какой практической задачи (или класса задач) сравниваете?

    Где-то достаточно $listener = new-object System.Net.HttpListener … $listener.Start(), а где-то нет

    Reply ↓
  15. pallid

    (14)

    Порт я надеюсь не вшит в приложение и может быть сконфигурирован извне?

    Да, его можно задать переменной окружения

    Вы для какой практической задачи (или класса задач) сравниваете?

    пока только в качестве небольших слабосвязанных как либо сервисов, в своем интранете

    Где-то достаточно $listener = new-object System.Net.HttpListener … $listener.Start(), а где-то нет

    вот хотелось бы как раз посмотреть как и для чего готовят такое

    Reply ↓
  16. blackhole321
    Да, его можно задать переменной окружения

    А два экземпляра на разных портах как ?

    вот хотелось бы как раз посмотреть как и для чего готовят такое

    Не понял, что Вы имеете ввиду?

    пока только в качестве небольших слабосвязанных как либо сервисов, в своем интранете

    Ну тогда имеет смысл использовать то, что удобнее, привычнее, то, чем лучше владеете, т.к. все более/менее современные технологии обеспечивают некий минимум, который я думаю покрывает подавляющее большинство простых задач.

    Reply ↓
  17. pallid

    (16)

    А два экземпляра на разных портах как ?

    в видноус да, в докер не пробовал (ну понятно почему)

    Не понял, что Вы имеете ввиду?

    раньше считал что лучше поднять для 1С apache и не напрягаться с IIS, нет тебе ковыряний после обновления платформы и т.п

    потом прочитал, что сами 1С вроде как рекомендуют использовать именно IIS, тем более в x64

    сам не пробовал, не имею опыт именно в эксплуатации, и со всеми проблемами с которыми можно столкнуться (проблемы транспорта, в чей власти сеть и т.п)

    просто как то так сложилось, что не особо положительно к IIS

    Reply ↓
  18. blackhole321

    (17)

    в видноус да

    Да — можно или Да — нельзя 🙂 ?

    что не особо положительно к IIS

    Нормальный web-сервер с хорошим функционалом и штатно из коробки.

    Если Вы платите деньги за систему, почему-бы не использовать имеющиеся возможности по максимуму?

    Reply ↓
  19. pallid

    (18)

    Если Вы платите деньги за систему, почему-бы не использовать имеющиеся возможности по максимуму?

    согласен, надо попробовать основательно разобраться в этом…

    Да — можно или Да — нельзя 🙂 ?

    Да, можно

    Reply ↓

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *