java – Spring:无法从防火墙后面使用RMI连接到JMX Server
我的
Spring应用程序运行在NAT防火墙(pfSense)后面的机器上.机器的内部IP是a.b.c.d,NAT IP是w.x.y.z
Spring配置的serviceUrl在端口1100上设置为我的内部IP(a.b.c.d),当我启动应用程序时,我提供以下开关: -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=w.x.y.z -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false 如上所示,我设置了-Djava.rmi.server.hostname = w.x.y.z,以便通过NAT连接到应用程序.我还打开了机器防火墙上的相关端口,并设置了从w.x.y.z:1100到a.b.c.d:1100的端口. 当我尝试使用w.x.y.z:1100上的jconsole从网络外部连接到应用程序时,我得到一个java.io.IOException:jmxrmi java.io.IOException: jmxrmi at sun.tools.jconsole.ProxyClient.checkSslConfig(ProxyClient.java:236) at sun.tools.jconsole.ProxyClient.<init>(ProxyClient.java:127) at sun.tools.jconsole.ProxyClient.getProxyClient(ProxyClient.java:483) at sun.tools.jconsole.JConsole$3.run(JConsole.java:524) Caused by: java.rmi.NotBoundException: jmxrmi at sun.rmi.registry.RegistryImpl.lookup(RegistryImpl.java:136) at sun.rmi.registry.RegistryImpl_Skel.dispatch(Unknown Source) at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:409) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267) at sun.rmi.transport.Transport$1.run(Transport.java:177) at sun.rmi.transport.Transport$1.run(Transport.java:174) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:173) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:744) at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:275) at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:252) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:378) at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source) at sun.tools.jconsole.ProxyClient.checkSslConfig(ProxyClient.java:234) 如果我尝试使用w.x.y.z:1099上的jconsole进行连接,则会收到java.rmi.ConnectException(连接被拒绝).如何在NATted防火墙之外公开我的JMX MBean? java.rmi.ConnectException: Connection refused to host: w.x.y.z; nested exception is: java.net.ConnectException: Operation timed out at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619) at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216) at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202) at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:129) at javax.management.remote.rmi.RMIServerImpl_Stub.newClient(Unknown Source) at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2373) at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:297) at sun.tools.jconsole.ProxyClient.tryConnect(ProxyClient.java:355) at sun.tools.jconsole.ProxyClient.connect(ProxyClient.java:313) at sun.tools.jconsole.VMPanel$2.run(VMPanel.java:292) Caused by: java.net.ConnectException: Operation timed out at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:579) at java.net.Socket.connect(Socket.java:528) at java.net.Socket.<init>(Socket.java:425) at java.net.Socket.<init>(Socket.java:208) at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40) at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:147) at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613) ... 9 more 有趣的是,我可以使用telnet连接到w.x.y.z上的两个端口(1099和1100). 我的Spring配置的相关部分是: <bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean"> <property name="port" value="1100" /> </bean> <bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean" depends-on="registry"> <property name="server" ref="mbeanServer" /> <property name="objectName" value="connector:name=rmi" /> <property name="serviceUrl" value="service:jmx:rmi://a.b.c.d:1100/jndi/rmi://a.b.c.d:1100/server" /> <property name="environment"> <props> <prop key="jmx.remote.jndi.rebind">true</prop> </props> </property> </bean> <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"> <!-- indicate to first look for a server --> <property name="locateExistingServerIfPossible" value="true"/> </bean> 注意:我没有使用任何servlet容器. 编辑:第一个答案为我提供了解决我的具体问题的基础,这可以在第二个答案中看到. 解决方法
使用com.sun.management.jmxremote.port定义的初始端口称为注册表端口,仅用于启动协商并确定用于“真实”通信的下一个端口. Java RMI机制使用动态分配的端口,通常与防火墙不兼容.
What port is used by Java RMI connection? 也就是说,对于JMX来说,可以解决它 a)使用系统属性锁定两个端口(需要Java 7) com.sun.management.jmxremote.port com.sun.management.jmxremote.rmi.port b)使用自定义代码请求特定端口.看到 也可以看看: > Why Java opens 3 ports when JMX is configured? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |