使用java rmi的优点和缺点

发布于 2024-08-23 18:19:37 字数 21 浏览 6 评论 0原文

RMI 的优点和缺点是什么?

What are the advantages and disadvantages of RMI?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

知足的幸福 2024-08-30 18:19:37

其优点和缺点与任何类似 RPC(远程过程调用)系统的优点和缺点类似。表面上看起来很简单,因为实际上远程的对象可以被视为本地对象。

这似乎对简化编程有很大好处,但也存在隐性成本。分布式系统存在延迟问题和潜在的部分故障,程序员必须意识到这些问题。远程方法的调用可能会因安全、延迟问题、网络故障等而出现潜在的故障。掩盖此类问题可能会对可靠性造成灾难。

The advantages and disadvantages are similar to those of any RPC-like (Remote Procedure Call) System. There is a superficial appearance of simplicity, because it objects which are in fact remote can be treated as though they were local.

This would seem like a great benefit to simplicity of programming, but there are hidden costs. Distributed systems have issues of latency and potential for partial failure which the programmer has to be aware of. An invocation of a remote method is subject to potential failure from security, latency problems, network failure, etc. Papering over these sorts of problems can be a disaster for reliability.

温柔一刀 2024-08-30 18:19:37

根据我的经验:

优点:

  • 易于启动
  • 动态类加载非常强大
  • 如果您实现如下所示的内容,您将无法在很长一段时间内更改服务器端并开发客户端(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();
    }

}

示例客户端 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 服务器在 PassedObject 上调用 method(),但是了不起的客户端可以覆盖这个方法并执行他想要的任何东西...
  • 很难实现在互联网上工作的回调(它需要建立从服务器到客户端的新连接 - 通过 NAT/路由器/防火墙传递它可能具有挑战性)
  • 当您在执行远程方法期间突然断开连接时,该方法不会返回(我建议将 rmi 调用包装到 Callable 中并在定义的超时下运行它们)。

From my experience:

Pros:

  • Easy to start
  • Dynamic class loading is very powerful
  • If you implement something like below you can not change server side for a long time and develop client (one exception on rmi server has to get these classes in classpath - so either server them over net or include them and rebuild server)

You can implement two interfaces like that:

Common task interface:

public interface Task<T extends Serializable> extends Serializable {

    T execute();

}

Rmi interface:

public interface RmiTask extends Remote {

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

}

RmiTask implementation on server side:

public class RmiTaskExecutor implements RmiTask {

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

}

Example client Task implementation:

public class IsFileTask implements Task<Boolean> {

    final String path;

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

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

}

Cons:

  • Could be insecure, when using Dynamic class loading (client serves implementation of passed types) - for example you know that rmi server calls method() on PassedObject, but marvellous client could override this method and execute whatever he wants there...
  • hard to implement callback which would work over Internet (it needs to establish new connection from server to client - it can be challenging to pass it through NAT/routers/ firewalls)
  • when you suddenly broke the connection during execution of remote method it happens that this method would not return (I recommend wrapping rmi calls into Callables and run them with defined timeouts).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文