Простая точка входа для одного сервиса RMI?

У меня есть несколько сервисов, которые экспортируют интерфейс RMI.

Раньше они предлагали это, создавая собственный реестр (с LocateRegistry.createRegistry) и привязывая его туда. Однако это стало невозможным, когда службы были перемещены для запуска как отдельные приложения в одной виртуальной машине (Tomcat), поскольку по какой-то причине там может присутствовать только один реестр.

Я работал над этим, используя центральный реестр для всех служб. Даже тогда меня не очень интересует роль реестра с несколькими объектами, а только его возможности точки входа. Однако центральный реестр вносит больше сложностей (например, он должен быть запущен первым, он должен иметь интерфейсы регистрируемых им служб).

Есть ли способ вернуть ситуацию, когда каждая служба независимо предлагает точку входа в свой интерфейс RMI, при этом запустив их на одной и той же виртуальной машине (что является деталью хостинга, а не частью дизайна)?


person Bart van Heukelom    schedule 09.07.2012    source источник


Ответы (3)


Я забыл, что уже задавал похожий вопрос (по другой причине, уменьшая код, прежде чем я переместил службы вместе в 1 виртуальную машину), где первый ответ предлагает способ обойти реестр:

Используйте UnicastRemoteObject, сериализуйте заглушку, полученную при экспорте объекта, и используйте общий файл, сокет или сеть, чтобы сделать заглушку доступной для клиентов.

person Bart van Heukelom    schedule 09.07.2012

У вас не может быть более одного реестра на JVM, потому что реестр имеет фиксированный идентификатор объекта RMI. Просто настройте все свои серверы так, чтобы они начинались так:

static Registry registry;
// ...
try
{
  registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
}
catch (...) // whatever the exception is, probably ExportException
{
  registry = LocateRegistry.locateRegistry(Registry.REGISTRY_PORT);
}
registry.rebind(...); // etc

Затем тот из них, который запустится первым, запустит реестр, а остальные будут его использовать.

person user207421    schedule 09.07.2012
comment
Я делал это какое-то время, но это еще более сложно и подвержено ошибкам. Тогда вся архитектура зависит от того, какая служба запустится первой. Если он останавливается/перезапускается, все остальные должны быть повторно связаны там и недоступны, пока служба 1 перезапускается. Кроме того, в код добавляется информация о хостинге (одна виртуальная машина). - person Bart van Heukelom; 10.07.2012
comment
@BartvanHeukelom Нет, не так. Неважно, какой сервер RMI запускается первым. Если все они сделают так, как указано выше, тот, который запустится первым, создаст реестр, а остальные найдут его. Я не знаю, какие «детали хостинга» задействованы, когда имя хоста даже не упоминается. - person user207421; 10.07.2012
comment
В самом деле, не имеет значения, какая запускается первой, но какая бы это ни была служба, тогда от нее зависит вся система, и ее нельзя остановить или перезапустить. Под деталями хостинга я подразумеваю, что тот факт, что приложения совместно используют виртуальную машину, является вопросом настройки хостинга/сервера, а не их дизайном. - person Bart van Heukelom; 10.07.2012
comment
@BartvanHeukelom Итак, теперь вы снова запускаете его как отдельный процесс. У вас не может быть и того, и другого. - person user207421; 10.07.2012
comment
Ну, я могу, используя вариант 3 из вашего ответа на другой вопрос. Но мне интересно, может ли клиент синтезировать всю удаленную заглушку, что было бы еще проще. - person Bart van Heukelom; 10.07.2012
comment
@BartvanHeukelom Ну, это еще один вопрос. Ответ «да», потому что locateRegistry() делает именно это, но вы должны экспортировать объект с фиксированным идентификатором объекта, что нетривиально, использует API Sun и т. д. Взгляните на locateRegistry() и исходный код RegistryImpl если вы хотите пойти по этому пути. - person user207421; 11.07.2012

Если вы все еще интересуетесь этой проблемой спустя год....

В одной JVM можно запустить несколько реестров. Просто вызовите LocateRegistry.getRegistry с разными портами. У вас должны быть хорошо известные порты для каждой службы, но я думаю, что вы уже делаете это, если реализовали вариант 3 из этого ответ на другой вопрос.

Давным-давно была ошибка, препятствовавшая сосуществованию нескольких реестров в одной и той же JVM, но она была исправлена ​​в JDK 5. В Tomcat может быть что-то, что препятствует запуску нескольких реестров RMI. Или, возможно, версия Tomcat, которую вы использовали, была поверх очень старой версии JDK.

person Stuart Marks    schedule 15.08.2013