论坛首页 Java企业应用论坛

JMX启动对外connectorserver服务经常性启动失败问题解决

浏览 10398 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-03-31   最后修改:2009-03-31
在系统中配置对外jmx服务的时候,经常出现端口绑定失败,有时候成功,有时候失败,不确定因素很大.
配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
   
    <bean id="producerTaskExecutorInfo" class="xxxx.ProducerTaskExecutorInfo" />

    <bean id="mbeanExporter" class="org.springframework.jmx.export.MBeanExporter">
        <property name="registrationBehaviorName" value="REGISTRATION_REPLACE_EXISTING" />
        <property name="beans">
            <map>
              <entry key="producerTaskExecutor" value-ref="producerTaskExecutorInfo" />
            </map>
        </property>
    </bean>
      
    <bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean">
       <property name="objectName" value="connector:name=rmi" />
       <property name="serviceUrl" value="service:jmx:rmi:///jndi/rmi://127.0.0.1:8880/jmxrmi" />
       <property name="threaded" value="true" />
       <property name="daemon" value="true" />
    </bean>
        
    <bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean" >
        <property name="port" value="8880" />
    </bean>
</beans> 


错误如下:
Exception in thread "JMX Connector Thread [service:jmx:rmi:///jndi/rmi://127.0.0.1:8880/jmxrmi]" org.springframework.jmx.JmxException: Could not start JMX connector server after delay; nested exception is java.io.IOException: Cannot bind to URL [rmi://127.0.0.1:8880/jmxrmi]: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:
    java.net.ConnectException: Connection refused: connect]
    at org.springframework.jmx.support.ConnectorServerFactoryBean$1.run(ConnectorServerFactoryBean.java:157)
Caused by: java.io.IOException: Cannot bind to URL [rmi://127.0.0.1:8880/jmxrmi]: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:
    java.net.ConnectException: Connection refused: connect]
    at javax.management.remote.rmi.RMIConnectorServer.newIOException(RMIConnectorServer.java:814)
    at javax.management.remote.rmi.RMIConnectorServer.start(RMIConnectorServer.java:431)
    at org.springframework.jmx.support.ConnectorServerFactoryBean$1.run(ConnectorServerFactoryBean.java:154)
Caused by: javax.naming.ServiceUnavailableException [Root exception is java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:
    java.net.ConnectException: Connection refused: connect]
    at com.sun.jndi.rmi.registry.RegistryContext.bind(RegistryContext.java:122)
    at com.sun.jndi.toolkit.url.GenericURLContext.bind(GenericURLContext.java:208)
    at javax.naming.InitialContext.bind(InitialContext.java:359)
    at javax.management.remote.rmi.RMIConnectorServer.bind(RMIConnectorServer.java:635)
    at javax.management.remote.rmi.RMIConnectorServer.start(RMIConnectorServer.java:427)
    ... 1 more
Caused by: java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is:
    java.net.ConnectException: Connection refused: connect
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:574)
    at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)
    at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
    at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:306)
    at sun.rmi.registry.RegistryImpl_Stub.bind(Unknown Source)
    at com.sun.jndi.rmi.registry.RegistryContext.bind(RegistryContext.java:116)
    ... 5 more
Caused by: java.net.ConnectException: Connection refused: connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)
    at java.net.Socket.connect(Socket.java:507)
    at java.net.Socket.connect(Socket.java:457)
    at java.net.Socket.<init>(Socket.java:365)
    at java.net.Socket.<init>(Socket.java:178)
    at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
    at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
    at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:569)
    ... 10 more


但是通过AMQ对外配置JMX服务的时候,却不会出现类似问题,很奇怪.
查看AMQ中对外connectServer配置对外实现,代码如下:

类:org.apache.activemq.broker.jmx.ManagementContext

private void createConnector(MBeanServer mbeanServer) throws MalformedObjectNameException, MalformedURLException, IOException {
        // Create the NamingService, needed by JSR 160
        try {
            LocateRegistry.createRegistry(connectorPort);
            namingServiceObjectName = ObjectName.getInstance("naming:type=rmiregistry");
            // Do not use the createMBean as the mx4j jar may not be in the
            // same class loader than the server
            Class cl = Class.forName("mx4j.tools.naming.NamingService");
            mbeanServer.registerMBean(cl.newInstance(), namingServiceObjectName);
            // mbeanServer.createMBean("mx4j.tools.naming.NamingService",
            // namingServiceObjectName, null);
            // set the naming port
            Attribute attr = new Attribute("Port", Integer.valueOf(connectorPort));
            mbeanServer.setAttribute(namingServiceObjectName, attr);
        } catch(ClassNotFoundException e) {
            LOG.debug("Probably not using JRE 1.4: " + e.getLocalizedMessage());
        }
        catch (Throwable e) {
            LOG.debug("Failed to create local registry", e);
        }
        // Create the JMXConnectorServer
        String rmiServer = "";
        if (rmiServerPort != 0) {
            // This is handy to use if you have a firewall and need to
            // force JMX to use fixed ports.
            rmiServer = "localhost:" + rmiServerPort;
        }
        String serviceURL = "service:jmx:rmi://" + rmiServer + "/jndi/rmi://localhost:" + connectorPort + connectorPath;
        JMXServiceURL url = new JMXServiceURL(serviceURL);
        connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbeanServer);
    }


看了多次,最后发现一个细微的地方
AMQ中先注册RMI端口
LocateRegistry.createRegistry(connectorPort);
然后创建connectorServer
而在我配置中顺序却是相反的.

修改配置顺序,并添加端口的销毁方法
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
   
    <bean id="producerTaskExecutorInfo" class="xxxx.ProducerTaskExecutorInfo" />

    <bean id="mbeanExporter" class="org.springframework.jmx.export.MBeanExporter">
        <property name="registrationBehaviorName" value="REGISTRATION_REPLACE_EXISTING" />
        <property name="beans">
            <map>
              <entry key="producerTaskExecutor" value-ref="producerTaskExecutorInfo" />
            </map>
        </property>
    </bean>
      
    <bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean" destroy-method="destroy">
        <property name="port" value="8880" />
    </bean>
      
    <bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean" depends-on="registry">
       <property name="objectName" value="connector:name=rmi" />
       <property name="serviceUrl" value="service:jmx:rmi:///jndi/rmi://127.0.0.1:8880/jmxrmi" />
       <property name="threaded" value="true" />
       <property name="daemon" value="true" />
    </bean>
  
</beans>   


总结:自己对rmi服务不熟悉.
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics