Подтвердить что ты не робот

Связь между местными JVM

Мой вопрос: Какой подход можно взять/должен использовать для связи между двумя или несколькими экземплярами JVM, которые работают локально?

Некоторое описание проблемы:
Я разрабатываю систему для проекта, который требует, чтобы отдельные экземпляры JVM полностью изолировали определенные задачи друг от друга.

При запуске "родительский" JVM создаст "дочерние" JVM, которые он будет ожидать, и затем вернет ему результаты (в формате относительно простых POJO-классов или, возможно, структурированных XML-данных). Эти результаты не должны передаваться с использованием SysErr/SysOut/SysIn, поскольку ребенок уже может использовать их как часть своего запуска.

Если дочерняя JVM не отвечает результатами в течение определенного времени, родительская JVM должна иметь возможность сигнализировать ребенку о прекращении обработки или убить дочерний процесс. В противном случае дочерняя JVM должна нормально выйти в конце выполнения своей задачи.

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

  • Использование библиотеки Java RMI
  • Использование сокетов для передачи объектов
  • Использование библиотек распространения, таких как Cajo, Hessian

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

Спасибо за любую помощь или совет по этому поводу!

редактирует:
Количество передаваемых данных - относительно небольшое, в основном это будет всего лишь несколько POJO, содержащих строки, которые будут представлять результат выполнения дочернего элемента. Если какое-либо решение будет неэффективным для больших объемов информации, это вряд ли будет проблемой в моей системе. Передаваемая сумма должна быть довольно статичной, и поэтому ее не нужно масштабировать.

Задержка передачи - не является серьезной проблемой в этом случае, хотя, если требуется какой-либо "опрос" результатов, это должно быть достаточно частым без значительных накладных расходов, поэтому я могу поддерживать отзывчивый GUI поверх этого в более позднее время (например, индикатор выполнения)

4b9b3361

Ответ 1

Я бы использовал KryoNet с локальными сокетами, так как он сильно специализируется на сериализации и довольно легкий (вы также получаете Remote Method Invocation! Я использую его прямо сейчас), но отключите тайм-аут отключения сокета.

RMI в основном работает по принципу, что у вас есть удаленный тип и что удаленный тип реализует интерфейс. Этот интерфейс является общим. На вашем локальном компьютере вы связываете интерфейс через библиотеку RMI с кодом "инъецированный" в память из библиотеки RMI, в результате у вас есть что-то, что удовлетворяет интерфейсу, но способно связываться с удаленным объектом.

Ответ 2

Непосредственно ответ на ваш вопрос, но предложение альтернативы. Вы считали OSGI?

Он позволяет запускать java-проекты в полной изоляции друг от друга, в рамках SAME jvm. Красота заключается в том, что общение между проектами очень просто с услугами (см. Основные характеристики PDF стр. 123). Таким образом, не выполняется "сериализация" любого вида, поскольку данные и вызовы находятся в одном и том же jvm.

Кроме того, все ваши требования к качеству обслуживания (время отклика и т.д.) уходят - вам нужно только беспокоиться о том, будет ли служба UP или DOWN в то время, когда вы хотите ее использовать. И для этого у вас действительно хорошая спецификация, которая для вас называется Declarative Services (см. Enterprise Spec PDF стр. 141)

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

Обновить

Чтобы ответить на вопрос о безопасности, я никогда не рассматривал такой сценарий. Я не верю, что есть способ обеспечить использование "памяти" в OSGI.

Однако существует способ связи вне JVM между различными режимами OSGI. Он называется Remote Services (см. Enterprise Spec PDF, стр. 7). У них также есть хорошая дискуссия о факторах, которые следует учитывать при выполнении чего-то подобного (см. 13.1 Fallalies).

Люди в Apache Felix (реализация OSGI) Я думаю, что это реализация с iPOJO, называемая "Распределенные сервисы с iPOJO" (их оболочка для создания используя услуги проще). Я никогда не использовал это - так игнорируй меня, если я ошибаюсь.

Ответ 3

akka - это еще один вариант, а также другой java-актер рамки, он обеспечивает связь и другие положительные эффекты, полученные из

Ответ 4

Если вы не можете использовать stdin/stdout, я бы пошел с сокетами. Вам нужен какой-то уровень сериализации поверх сокетов (как и для stdin/stdout), а RMI - очень простой в использовании и довольно эффективный такой уровень.

Если вы использовали RMI и обнаружили, что производительность недостаточно, я бы переключился на более эффективный сериализатор - есть множество опций.

Я бы не стал приближаться к веб-сервисам или XML. Это похоже на полную трату времени, скорее всего, потребует больше усилий и обеспечивает меньшую производительность, чем RMI.

Ответ 5

Не многие люди, похоже, больше любят RMI.

Параметры:

  • Веб-службы. например http://cxf.apache.org
  • JMX. Теперь это действительно средство использования RMI под таблицей, но это сработает.
  • Другие протоколы IPC; вы привели Hessian
  • Сворачивать самостоятельно, используя сокеты или даже разделяемую память. (Откройте сопоставленный файл в родительском, откройте его снова в дочернем элементе. Вам все равно потребуется что-то для синхронизации.)

Примерами примечаний являются Apache ant (который разворачивает все виды Jvms для той или иной цели), Apache maven и вариант с открытым исходным кодом набора для демонстрации Tanukisoft.

Лично я очень легко отношусь к веб-сервисам, так что молоток, который я стараюсь превращать в гвозди. Типичная служба JAX-WS + JAX-B или JAX-RS + JAX-B - очень маленький код с CXF и управляет всей сериализацией данных и десериализацией для меня.

Ответ 6

Это было упомянуто выше, но я хотел немного расширить предложение JMX. мы фактически делаем то, что вы планируете делать (от того, что я могу почерпнуть из ваших различных комментариев). мы приземлились на использование jmx по целому ряду причин, некоторые из которых я упомянул здесь. Во-первых, jmx - это все о менеджменте, поэтому в целом он идеально подходит для того, что вы хотите сделать (особенно если вы уже планируете использовать jmx-услуги для других задач управления). любые усилия, которые вы вкладываете в интерфейсы jmx, будут выполнять двойной долг, как и apis, который вы можете вызвать с помощью инструментов управления java, таких как jvisualvm. это приводит к моему следующему пункту, который наиболее важен для того, что вы хотите. новый Attach API в jdk 6 и выше очень приятен. он позволяет динамически обнаруживать и общаться с запущенными jvms. это позволяет, например, для вашего процесса "контроллера" сбой и перезапуск и повторное обнаружение всех существующих рабочих процессов. это постановки очень надежной системы. было упомянуто выше, что jmx в основном rmi под капотом, однако, в отличие от использования rmi напрямую, вам не нужно управлять всеми деталями соединения (например, имея дело с уникальными портами, возможностью обнаружения и т.д.). attach api - это немного скрытый камень в jdk, поскольку он не очень хорошо документирован. когда я сначала врывался в этот материал, я не знал названия api, поэтому выяснение того, как "волшебство" в jvisualvm и jconsole работало, было очень сложно. наконец, я столкнулся с такой статьей, как этот, в котором показано, как реально использовать приложенную api динамически в вашей собственной программе.

Ответ 7

Хотя он предназначен для потенциально удаленной связи между JVM, я думаю, вы обнаружите, что Netty отлично работает между локальными экземплярами JVM как хорошо.

Это, вероятно, самая эффективная/надежная/широко поддерживаемая библиотека своего типа для Java.

Ответ 8

Много обсуждается выше. Но будь это сокеты, rmi, jms - есть часть грязной работы. Я бы посоветовал akka. Это актерская модель, которая обменивается данными друг с другом с помощью сообщений.

Красота заключается в том, что актеры могут быть на одной JVM или другой (очень маленькая конфигурация), а акка заботится о вас остальным. Я не видел более чистого способа, чем делать это:)

Ответ 9

Попробуйте jGroups, если данные, которые будут переданы, не огромны.

Ответ 10

Как вы упомянули, вы можете явно отправлять объекты по сети, но это дорогостоящая вещь, не говоря уже о запуске отдельной JVM.

Другой подход, если вы просто хотите разделить свои разные миры внутри одной JVM, - это загрузить классы с разными загрузчиками классов. ClassA @CL1!= ClassA @CL2, если они загружаются CL1 и CL2 в качестве загрузчиков классов sibling.

Чтобы включить обмен данными между classA @CL1 и classA @CL2, у вас может быть три загрузчика классов.

  • CL1, который загружает process1
  • CL2, который загружает process2 (те же классы, что и в CL1)
  • CL3, который загружает классы связи (POJO и Service).

Теперь вы позволяете CL3 быть родительским загрузчиком классов CL1 и CL2.

В классах, загружаемых CL3, вы можете иметь легкую коммуникационную функцию отправки/получения (send (Pojo)/receive (Pojo)) POJO между классами в CL1 и классами CL2.

В CL3 вы предоставляете статическую службу, которая позволяет реализации из CL1 и CL2-регистра отправлять и получать POJO.