5

我们有一个应用程序,它使用 MBeanServerConnection.invoke 在 MBean 上调用各种远程方法。有时,这些方法之一会挂起。有没有办法让通话超时?如果调用时间过长,它会返回异常吗?

或者我是否必须将所有这些调用移动到单独的线程中,这样它们就不会锁定 UI 并需要终止应用程序?

4

3 回答 3

3

See http://weblogs.java.net/blog/emcmanus/archive/2007/05/making_a_jmx_co.html

===== Update =====

I was thinking about this stuff when I first responded, but I was on my mobile and I can't type worth a damn on it.....

This is really an RMI problem, and unless you use a different protocol, there's not much you can do, except, as you say, move all those calls into separate threads so they don't lock up the UI.

But.... if you have the option of fiddling with the target server and you can customize the connecting client, you have at least 1 option which is to customize the JMXConnectorServer on your target servers.

The standard JMXConnectorServer implementation is the RMIConnectorServer. Part of it's specification is that when you create a new instance using any of the constructors (like RMIConnectorServer(JMXServiceURL url, Map environment)), the environment map can contain a key/value pair where the key is RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE and the value is a RMIClientSocketFactory. Therefore, you can specify a socket factory method like this:

RMIClientSocketFactory clientSocketFatory = new RMIClientSocketFactory() {
   public Socket createSocket(String host, int port) {
      Socket s = new Socket(host, port);
      s.setSoTimeout(3000);
   }
};

This factory creates a Socket and then sets its SO_TIMEOUT using setSoTimeout, so when the client connects using this socket, all operations, including connecting, will timeout after 3000 ms.

You could also checkout the JMXMP connector and server in the jmx-optional package of the OpenDMK. (links are to my github mavenized). No built in solution, mind you, but they're super easy to extend and JMXMP is simple TCP socket based rather than RMI, so this type of customization would be trivial.

Cheers.

于 2012-06-04T21:45:26.030 回答
1

@ Nicholas:上面的代码不起作用。我的意思是请求在 3000.ms 之后没有超时。

map.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE,新的 RMIClientSocketFactory() {

            @Override
            public Socket createSocket(String host, int port) throws IOException {
                if(logger.isInfoEnabled() ){
                    logger.info("JMXManager inside createSocket..." + host + ": port :" + port);
                    }
                  Socket s = new Socket(host, port);
                  s.setSoTimeout(3000);
                  return s;
            }
        });

        cs = JMXConnectorServerFactory.newJMXConnectorServer(url,map,mbeanServer);
于 2013-09-09T06:58:28.973 回答
0

正如我回答的那样:如何为 JMX 连接器设置请求超时, RMI 属性可以为您提供帮助。所有属性都在 Oracle 文档站点上: http: //docs.oracle.com/javase/7/docs/technotes/guides/rmi/sunrmiproperties.html

例如:-Dsun.rmi.transport.tcp.responseTimeout=60000是客户端 tcp 响应超时。还有连接超时和服务器端连接的属性。

我也很不高兴 JMX/RMI/TCP 堆栈如何从较低级别的协议中隐藏重要设置,并使其无法用于单个连接。

于 2013-12-18T11:59:24.627 回答