4

我正在尝试通过 JMX 启用我的核心 java 应用程序以进行远程访问。然而,有两个限制使它变得比应有的更难。

a) 我无权更改在 linux 机器上启动应用程序的脚本。因此,我无法将任何“jmxremote”参数传递给 jvm。

b) 我指定的远程端口 ( ) 很可能com.sun.management.jmxremote.port = xxxx没有打开,我无法修改脚本以尝试另一个打开的端口。我必须自动完成。

我试图通过编写一个类来绕过这些限制,该类将设置所有必需的 jmxremote 参数并找到一个“免费”端口。

public class JmxRemoteConnectionHelper{

    @Override
    public void init( ) throws Exception{

        InetAddress address = InetAddress.getLocalHost();
        String ipAddress    = address.getHostAddress();
        String hostname     = address.getHostName();
        String port         = String.valueOf( getFreePort( ) );

        System.setProperty("java.rmi.server.hostname", ipAddress );
        System.setProperty("com.sun.management.jmxremote", "true" );
        System.setProperty("com.sun.management.jmxremote.authenticate", "false" );
        System.setProperty("com.sun.management.jmxremote.ssl", "false" );
        System.setProperty("com.sun.management.jmxremote.port", port  );

    }

    private final int getFreePort( ){

        **//seedPort is passed in the constructor**
        int freePort            = seedPort;
        ServerSocket sSocket    = null;

        for( int i=ZERO; i<PORT_SCAN_COUNTER; i++ ){

            try{

                freePort        = freePort + i;
                sSocket         = new ServerSocket( freePort );

               //FOUND a free port.             
                break;

            }catch( Exception e ){
                //Log

            }finally{

                if( sSocket != null ){
                    try{
                            sSocket.close();
                        sSocket = null;
                    }catch(Exception e ){
                    //Log
                    }

                }
            }

        }

        return freePort;
    }

 }

如下图,我,然后通过spring初始化它。

<bean id="JmxRemoteConnection" class="JmxRemoteConnectionHelper" init-method="init" />

<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean" depends-on="JmxRemoteConnection" />   

<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false" >
        <property name="assembler"      ref="assembler"/>
        <property name="namingStrategy" ref="namingStrategy"/>
        <property name="autodetect"     value="true"/>
        <property name="server"         ref="mbeanServer"/>
</bean>

<bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>

<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
        <property name="attributeSource" ref="jmxAttributeSource"/>
</bean>

<bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy" lazy-init="true">
        <property name="attributeSource" ref="jmxAttributeSource"/>
</bean>

为了测试,我在我的 Windows 机器上启动了该应用程序。它正确启动。但是,当我在同一个框中打开 JConsole并尝试通过“远程进程” (ip:端口)进行连接时,我在底部收到“连接被拒绝”消息。

我怀疑 JMX 代理没有看到我正在设置的任何远程系统属性。

我正在使用JDK 1.6

4

2 回答 2

6

由于您已经在使用 Spring,我认为您应该看看使用ConnectorServerFactoryBeancan 是否可以做您想做的事情。我从来不需要启动远程 JMX 服务器,但看起来这就是该对象可以为您做的事情。

于 2013-03-22T01:00:50.507 回答
3

请参阅此问题的答案以在流程中启用 jmx:

是否可以以编程方式启用远程 jmx 监控?

To find a free port simply wrap LocateRegistry.createRegistry() in a loop which retries with a new port number until it succeeds. Of course you'll have to communicate the final port number to whatever needs to connect. Alternatively running jstatd on the host should make it discoverable

于 2018-05-23T11:40:44.533 回答