Динамическое выполнение кода 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 не будет опубликован. Обязательные поля помечены *