Zorkus
@Zorkus

Запуск большого количества параллельных задач в отдельных песочницах?

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


Предлагаю порассуждать на тему возможных решений.


Итак, есть крупное Enterprise-решение, написанное на Java. Как часть своей функциональности, оно предлагает пользователям возможность создавать собственные скрипты, написанные на некотором языке, которые запускаются на выполнение в песочницах, и возвращают некоторый результат. По замыслу, это именно что чистые функции — принимают значения, производят вычисления над ними, возвращают результат, все. Никаких обращений к внешним ресурсам, никаких side effects. Скриптов этим может запускаться на выполнение много — сотни в минуту, примерно так. Возникает вопрос, как организовать надежную песочницу для них.




Предположим, мы будем использовать в качестве языка для этих скриптов Jython/Groovy/JRuby, какой угодно скриптовый язык под JVM, так как остальная часть системы написана на Java.


Сразу проблема — штатные средства JVM/архитектура Windows/Unix не позволяют организовать песочницу в рамках родительского процесса, в котором выполняется основная программа. Ограничение доступа к частям JDK по списку разрешенных пакетом, система пермишенов на доступ к сети, файлам, и все прочее хорошо, но одно но — нет никакого нормального способа запретить скрипту выполнить new int[10000000000000] и свалить JVM с OutOfMemory, тупо потому, что весь heap расшаривается между всеми потоками процесса, и ничего с этим поделать нельзя (строго говоря, единственный теоритический способ, это перехватывать все операции выделения памяти с помощью jvm agent, и не запускать на выполнение байткоды, запрашивающие выделение памяти через new, без проверки того, сколько памяти запрашивается… это потребует написание агента, который модифицирует байткод всех загружаемых классов, и вставляет нужные проверки вокруг всех операций выделения памяти, в том числе внутри самих классов JDK… мрак).


Т.е. для каждого скрипта нам нужен отдельный процесс. Но раз так, то JVM нам сразу для этого мало подходит. Потому что она изначально не предназначена для выполнения одноразовых скриптов, она имеет большой оверхед по запуску, инициализации рантайма (даже для client jvm), она потребляет много памяти на каждый свой процесс (в том числе потому, что на каждый процесс требуется создавать свой perm gen, в который грузятся все классы… и даже class data sharing вряд ли радикально сократит потребление памяти, хотя тут я еще собираюсь поэкспериментировать).


Следующий вариант — использовать для этих скриптов что-то вроде питона, и запускать его нативные процессы (под юниксом, через форк), считая что так они будут создаваться намного быстрее… Интегрироваться с этими процессами из основной программы можно либо по TCP, либо через pipes.


Питон как язык удобен для того, чтобы пользователи писали скрипты именно на нем. Возникает вопрос, как обстоят дела с sandboxing у Питона, по аналогии с Java Security Manager.


Следующий вариант — использовать язык типа Erlang, в котором порождение процессов гораздо проще, но и сам язык гораздо более экзотический…


Итак, господа, какие будут идеи? Может, стоит этот вопрос запостить как независимый топик в блог Java?
  • Вопрос задан
  • 2666 просмотров
Пригласить эксперта
Ответы на вопрос 4
bagyr
@bagyr
Вынести вычисления в отдельную (одну или несколько) постоянно работающую JVM, общаться с ними по любому IPC, исполнять скрипты там и как-то мониторить состояние машин, перезапуская в случае падения. Если глянуть на akka (akka.config.Supervision, например), то велосипедов может быть меньше.

С питоном идея совсем плохая, на эрланге замутить можно, но муторно и непонятно зачем.
Ответ написан
Комментировать
@dborovikov
Я думаю наиболее надежный способ создания песочниц — это поднятие контейнера вроде LXС. Попробуйте держать пул таких контейнеров и выдавать их пользователям по требованию. Общение можно сделать достаточно просто с помощью, например Spring Invoker. Точно я вам не подскажу, так как не спец в виртуализации, но копать нужно куда-то в эту сторону. Например посмотрите как делают облачные хостеры, ведь для них проблема создания «песочниц» одна из наиболее актуальных.
Ответ написан
Комментировать
Zorkus
@Zorkus Автор вопроса
Использование JVM мне тут нравится всем, кроме одного — память. В моем понимании, при запуске для таких целей, оверхед под памяти у JVM будет много больше, чем у Питона.
Ответ написан
Комментировать
@RomanPyr
Можно организовать песочницу для javascripts на основе node.js
Подробности здесь:
Выполнение javascript кода в песочнице на сервере
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Bell Integrator Ульяновск
До 400 000 ₽
Bell Integrator Хабаровск
До 400 000 ₽
Bell Integrator Ижевск
До 400 000 ₽