2010-02-26 2 views

ответ

12

Преимущества и недостатки подобны преимуществам любой RPC-подобной (Remote Procedure Call) системы. Существует поверхностное появление простоты, потому что объекты, которые на самом деле удалены, можно трактовать так, как если бы они были локальными.

Это может показаться большой выгодой для простоты программирования, но есть скрытые затраты. Распределенные системы имеют проблемы с задержкой и возможностью частичного отказа, о которых должен знать программист. Вызов удаленного метода подвержен потенциальному отказу от безопасности, проблем с задержкой, сбою сети и т. Д. Бумага по этим типам проблем может стать катастрофой для надежности.

Waldo et al. хорошо обсуждают проблемы.

+0

Спасибо за ссылку на бумагу. Я могу прекрасно использовать это в своем тезисе :) – Daff

+0

Хорошо сказано. Хотя я написал книгу о RMI, я на самом деле не сторонник.Это делает вещи кажущимися простыми, которые очень далеки от простых, и это усложняет работу, что на самом деле не так сложно, например. «Я должен повторить?» – EJP

+3

Ссылка на «Waldo et al» больше не существует: | –

5

Из моего опыта:

Pros:

  • Легко начать
  • Динамическая нагрузка класса является очень мощным
  • Если вы реализуете что-то, как показано ниже, вы не можете изменить на стороне сервера в течение длительного время и развитие клиента (одно исключение на сервере rmi должно получить эти классы в пути к классам - так что либо они передают их по сети, либо включают их, либо восстанавливают сервер)

Вы можете реализовать два интерфейса так:

Общий интерфейс Задача:

public interface Task<T extends Serializable> extends Serializable { 

    T execute(); 

} 

Rmi интерфейс:

public interface RmiTask extends Remote { 

    <T extends Serializable> T executeTask(Task<T> task) throws RemoteException; 

} 

RmiTask реализация на стороне сервера:

public class RmiTaskExecutor implements RmiTask { 

    public <T extends Serializable> T executeTask(Task<T> task) { 
     return task.execute(); 
    } 

} 

Exampl е клиент Task реализация:

public class IsFileTask implements Task<Boolean> { 

    final String path; 

    public IsFileTask(String path) { 
     this.path = path; 
    } 

    public Boolean execute() { 
     return new File(path).isFile(); 
    } 

} 

Минусы:

  • Может быть небезопасно, при использовании динамической загрузки класса (клиент обслуживает реализацию передаваемых типов) - например, вы знаете, что сервер RMI вызывает method() на PassedObject, но замечательный клиент может переопределить этот метод и выполнить все, что он там хочет ...
  • сложно реализовать обратный вызов, который будет работать через Интернет (ему нужно установить новое соединение с сервера на клиента - может быть сложно передать его через NAT/маршрутизаторы/брандмауэры)
  • , когда вы внезапно нарушили соединение во время выполнения удаленного метода, бывает так, что этот метод не вернется (я рекомендую обматывать вызовы rmi в Callable и запускать их с определенными таймаутами).
Смежные вопросы