非本地环境下Java RMI远程连接异常求助
Java RMI远程部署连接拒绝问题解决思路
核心问题分析
你遇到的localhost连接被拒绝错误,本质是RMI服务端返回给客户端的Stub对象仍然指向localhost,而非你设置的外部IP,导致客户端尝试连接本地而非远程服务器。以下是针对性解决步骤:
1. 修正java.rmi.server.hostname设置方式
服务端的java.rmi.server.hostname必须在所有RMI对象创建前生效,代码中设置的时机没问题,但更可靠的方式是通过JVM启动参数设置,避免代码执行顺序导致的失效:
# 服务端启动时添加 -Djava.rmi.server.hostname=42.155.241.914
同时删掉客户端中多余的System.setProperty("java.rmi.server.hostname","42.155.241.914");——这个属性仅服务端需要,客户端设置会造成干扰。
2. 调整Registry绑定逻辑
避免使用Naming.bind的URL格式,直接通过Registry对象绑定,减少解析错误:
// 服务端代码修改 try { System.setProperty("java.rmi.server.hostname","42.155.241.914"); Registry registry = LocateRegistry.createRegistry(1099); RemoteService rs = new RemoteService(); registry.bind("RemoteBookService", rs); // 直接绑定到Registry System.out.println("Service started"); } catch (Exception e) { e.printStackTrace(); System.out.println("could not start registry"); }
3. 固定RMI通信端口并开放防火墙
RMI默认会随机分配Stub通信端口,导致防火墙无法提前放行。可以手动指定端口:
// 服务端代码中,导出Remote对象时指定固定端口 RemoteService rs = new RemoteService(); UnicastRemoteObject.exportObject(rs, 1234); // 固定端口1234 registry.bind("RemoteBookService", rs);
然后在服务器防火墙中开放两个端口:
- 1099(Registry端口)
- 1234(你指定的Stub通信端口)
同时在客户端测试端口连通性:
# 测试Registry端口 telnet 42.155.241.914 1099 # 测试Stub通信端口 telnet 42.155.241.914 1234
如果连接失败,优先排查防火墙/安全组配置。
4. 配置RMI安全策略
远程RMI要求安全策略文件,服务端和客户端都需要创建policy.policy文件:
grant { permission java.security.AllPermission; };
启动时添加JVM参数加载策略:
# 服务端和客户端启动时都添加 -Djava.security.policy=policy.policy
5. 验证服务器网络配置
- 确认服务器的外部IP
42.155.241.914是公网可访问的,而非内网IP - 检查服务器是否禁用了ICMP(ping),但ping不通不代表端口不可用,优先用telnet测试端口
内容的提问来源于stack exchange,提问作者flying_kaktus
相关产品推荐
相关产品推荐

