Как быстро проверить реестр RMI?

1

Я пытаюсь реализовать Алгоритм консенсуса Плотов для проекта распределенной системы.

Мне нужен очень быстрый способ узнать, доступен ли сервер A с сервера B и A Distributed System. Другими словами, может случиться, что A достигнут B, но облачная система A еще не поднята. Поэтому я думаю, что InetAddress.getByName(ip).isReachable(timeout); недостаточно.

Поскольку каждый заглушка сервера переименовывается в имя сервера, я решил получить реестр сервера и проверить, существует ли заглушка с тем же именем сервера: если это не так, то перейдите к следующему серверу, в противном случае выполните lookup (который может занять некоторое время). Это часть кода:

try {
    System.out.println("Getting "+clusterElement.getId()+" registry");
    Registry registry = LocateRegistry.getRegistry(clusterElement.getAddress());
    System.out.println("Checking contains:");
    if(!Arrays.asList(registry.list()).contains(clusterElement.getId())) {
        System.out.println("Server "+clusterElement.getId()+" not bound (maybe down?)!");
        continue;
    }
    System.out.println("Looking up "+clusterElement.getId()+" stub");
    ServerInterface stub = (ServerInterface) registry.lookup(clusterElement.getId());
    System.out.println("Asking vote to "+clusterElement.getId());
    //here methods are called on stub (exploiting costum SocketFactory)
} catch (NoSuchObjectException | java.rmi.ConnectException | java.rmi.ConnectIOException e){
    System.err.println("Candidate "+serverRMI.id+" cannot request vote to "+clusterElement.getId()+" because not reachable");
} catch (UnmarshalException e) {
    System.err.println("Candidate " + serverRMI.id + " timeout requesting vote to " + clusterElement.getId());
} catch (RemoteException e) {
    e.printStackTrace();
} catch (NotBoundException e) {
   System.out.println("Candidate "+serverRMI.id+" NotBound "+clusterElement.getId());
}

Теперь проблема в том, что сервер застревает в строке contains(), так как сообщение Checking contains напечатано, а Looking up... is not.

Почему это происходит? Есть ли способ ускорить процесс? Этот алгоритм FULL тайм-аутов, поэтому любое предложение будет действительно оценено!

UPDATE: после -Dsun.rmi.transport.tcp.responseTimeout=1 -Dsun.rmi.transport.proxy.connectTimeout=1 -Dsun.rmi.transport.tcp.handshakeTimeout=1 всех возможных свойств VM о тайм- -Dsun.rmi.transport.tcp.responseTimeout=1 -Dsun.rmi.transport.proxy.connectTimeout=1 -Dsun.rmi.transport.tcp.handshakeTimeout=1 RMI, например: -Dsun.rmi.transport.tcp.responseTimeout=1 -Dsun.rmi.transport.proxy.connectTimeout=1 -Dsun.rmi.transport.tcp.handshakeTimeout=1 Я вообще не видел никакой разницы, даже если исключение должно было быть выброшено при каждой операции RMI (так как каждый таймаут установлен на 1 мс!).

Единственное решение, которое я выяснил для этой проблемы, - это RMISocketFactory реализация RMISocketFactory:

final int timeoutMillis = 100;            
RMISocketFactory.setSocketFactory( new RMISocketFactory()
            {
                public Socket createSocket( String host, int port )
                        throws IOException
                {
                    Socket socket = new Socket();
                    socket.setSoTimeout(timeoutMillis);
                    socket.connect(new InetSocketAddress(host, port), timeoutMillis);
                    return socket;
                }

                public ServerSocket createServerSocket( int port )
                        throws IOException
                {
                    return new ServerSocket( port );
                }
            } );
Теги:
rmi
rmiregistry

1 ответ

0
Лучший ответ

Он застревает в Registry.list(). В конечном итоге это закончится.

Вам будет лучше просто вызвать lookup() без этого предыдущего шага, который не добавит никакого значения, и исследует все параметры таймаута, упомянутые на двух страницах свойств, связанных с домашней страницей RMI.

  • 0
    Спасибо за ваш ответ, но я думаю, что документ Java о свойстве RMI совершенно беспорядок. В любом случае, я обновил исходный вопрос, включая SocketFactory, который я использую для тайм-аута вызовов метода заглушки. Считаете ли вы, что этот тайм-аут также используется для работы с loookup ?
  • 0
    Ваша фабрика сокетов только устанавливает таймауты чтения. Он также должен установить время ожидания подключения, но даже тогда он не будет делать ничего, что не может контролироваться системными свойствами, на которые я ссылался. Документация была достаточной для меня, чтобы понять это. Я предлагаю вам постараться.
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню