Как подключить 2 JVM друг к другу
У меня следующая ситуация:
У меня есть 2 процесса JVM (действительно 2 java
процессы, выполняемые отдельно, а не 2 потока), запущенные на локальной машине. Назовем их ProcessA
a ProcessB
.
Я хочу, чтобы они связывались (обменивались данными) друг с другом (например, ProcessA
отправляет сообщение в ProcessB
, чтобы что-то сделать).
Теперь я обойду эту проблему, написав временный файл, и этот процесс периодически просматривает этот файл, чтобы получить сообщение. Я думаю, что это решение не так хорошо.
Что было бы лучшей альтернативой для достижения того, что я хочу?
Ответы
Ответ 1
Несколько опций IPC:
Сеть на основе сокетов (Bare-Bones)
- не обязательно жесткий, но:
- может быть многословным для небольшого числа,
- может предложить больше поверхностей для ошибок, поскольку вы пишете больше кода.
- вы можете полагаться на существующие фреймворки, например Netty
- Технически, это также сетевая связь, но прозрачная для вас.
Полноценные архитектуры передачи сообщений
- обычно используется как для RMI, так и для сетевых коммуникаций, но с поддержкой сложных разговоров и рабочих процессов
- может быть слишком тяжелым для чего-то простого.
- такие как ActiveMQ или JBoss Messaging
- больше предназначен для управления и мониторинга JVM, но может помочь реализовать то, что вам нужно, если вы в основном хотите иметь один запрос процесса другой для данных или отправить его запрос на действие, если они не слишком сложны.
- также работает над RMI (среди других возможных протоколов).
- не так просто обернуть голову сначала, но на самом деле довольно просто использовать
Обмен файлами/блокировка файлов
- что вы делаете прямо сейчас
- это выполнимо, но есть много проблем для обработки
Сигналы
- Вы можете просто отправить сигналы другому проекту.
- Однако он довольно ограничен и требует, чтобы вы реализовали уровень перевода (он был выполним, хотя, но довольно сумасшедшая идея играть с чем-либо серьезным.
Без каких-либо подробностей простой подход IPC на основе сети лучше всего выглядит так:
- наиболее расширяемый (с точки зрения добавления новых функций и рабочих процессов в ваш
- самый легкий (с точки зрения объема памяти для вашего приложения)
- самый простой (с точки зрения дизайна)
- наиболее образовательными (с точки зрения изучения способов внедрения МПК). (как вы сказали, "сокет жесткий" в комментарии, и это действительно не так и должно быть чем-то, над чем вы работаете)
При этом, основываясь на вашем примере (просто запрашивая другой процесс для выполнения действия), JMX также может быть достаточно хорош для вас.
Ответ 2
Я добавил библиотеку на github под названием Mappedbus (http://github.com/caplogic/mappedbus), которые позволяют двум (или многим другим) Java-процессам/JVM связываться, обмениваясь сообщениями. Библиотека использует файл с отображением памяти и использует функцию "выборка и добавление" и "изменчивость" чтения/записи для синхронизации разных читателей и писателей. Я измерил пропускную способность между двумя процессами, используя эту библиотеку, до 40 миллионов сообщений/с со средней задержкой в 25 нс для чтения/записи одного сообщения.
Ответ 3
То, что вы ищете, это inter-process communication
. Java предоставляет простую платформу IPC в виде API Java RMI. Существует несколько других механизмов межпроцессного взаимодействия, таких как каналы, сокеты, очереди сообщений (очевидно, что это все концепции, поэтому существуют платформы, которые их реализуют).
Я думаю, что в вашем случае Java RMI или простой реализации сокета должно быть достаточно.
Ответ 4
Сокеты с потоком DataInput (Output), для отправки объектов Java взад и вперед. Это проще, чем использование дискового файла и намного проще, чем Netty.
Ответ 5
Я склонен использовать jGroup для формирования локальных кластеров между процессами. Он работает для узлов (например, процессов) на одном компьютере, в одном JVM или даже на разных серверах.
Как только вы поймете основы, вам легко работать с ним, и у вас есть возможность фактически запускать два или более процесса в одной JVM, что позволяет легко протестировать эти процессы.
Накладные расходы и задержка минимальны, если оба находятся на одной машине (обычно только роутинг TCP около 100 нс на действие).
Ответ 6
Я думаю, что сокет может быть лучшим выбором.
Ответ 7
Еще в 2004 году я реализовал код, который выполняет работу с сокетами. До тех пор я много раз искал лучшее решение, потому что подход с сокетами запускает брандмауэр, и мои клиенты беспокоятся. Там нет лучшего решения до сих пор. Клиент должен сериализовать ваши данные, отправить и сервер должен получить и десериализовать.
Это легко.