在Tomcat,WebLogic,Glassfish等中使用哪个MBeanServer?

时间:2012-10-30 18:28:21

标签: java-ee tomcat glassfish weblogic jmx

我目前正在研究http://truevfs.java.net,一个用于Java的虚拟文件系统。 TrueVFS是模块化的,使用插件架构在运行时加载功能,而无需进行任何配置。一些可选插件使用平台MBeanServer来注册具有已定义ObjectNames的MBean以进行监视和管理。

现在我的一些用户正在将WARV中的TrueVFS JAR捆绑到Tomcat等人。除非它们包含一个启用JMX的插件并在不同的上下文中部署WAR的几个实例,否则这样可以正常工作。

这不起作用,因为每个Web应用程序都有自己的JMX启用插件的类加载器定义,但它们都将共享相同的平台MBeanServer并使用相同的ObjectNames来注册它们的MBean,所以有碰撞。

现在我该如何解决这个问题?我已经抽象了MBeanServer查找,以便我可以将它提取到另一个插件中,但我无法确定一个通常适用的策略,MBeanServer我应该使用它来注册我的MBean。

我搜索了主题并发现了一些documentation for WebLogic,表明我应该使用JNDI查找MBeanServer。但是,这似乎是WebLogic特有的。

不是一般的“一刀切”方法吗?


更新

这里是使用附加属性识别Web应用程序定义的类加载器的快速概念验证:

import java.lang.management.ManagementFactory;
import javax.management.JMX;
import javax.management.MBeanServer;
import javax.management.ObjectName;

public class Messenger implements MessengerMXBean {

    private static MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

    public static void main(String[] args ) throws Exception {
        register("one");
        register("two");
        find();
        System.out.println("Waiting for interrupt...");
        Thread.sleep(Long.MAX_VALUE);
    }

    private static void register(String context) throws Exception {
        mbs.registerMBean(new Messenger(),
                new ObjectName(":type=Messenger,context=" + context));
    }

    private static void find() throws Exception {
        for (ObjectName name : mbs.queryNames(new ObjectName(":type=Messenger,*"), null))
            System.out.println(JMX.newMXBeanProxy(mbs, name, MessengerMXBean.class).getMessage());
    }

    public String getMessage() { return "Hello world!"; }
}

public interface MessengerMXBean { String getMessage(); }

正如预期的那样,这个程序注册了两个Messenger MBean,找到它们并打印出他们的“Hello world!”#34;消息。

但是,此解决方案存在缺点:

  • 我必须将其他属性作为标识符进行模拟。理想情况下,这将是类加载器的标识符,这样我就可以保持通用目的,即不必为Web应用程序做特殊考虑。
  • 查找MBean现在需要考虑多个类加载器的特殊情况,即MBean的多个实例,只有它们的附加限定符才有所不同,即使应用程序是独立运行的。

这些是严重的限制,但似乎我没有更好的选择,所以我可能会这样做。

1 个答案:

答案 0 :(得分:4)

您可以为每个war模块重新创建一个新的MBeanServer。但是,当从外部查询JSR-160客户端时,您还需要指定MBeanServer。

当您使用Jolokia时,您将获得JVM的所有MBeanServers的透明合并。但是,当你拥有相同名称的MBean,只有一个可以访问时,这在这里不会有帮助。

我遇到这种情况的解决方案是使用相同的MBeanServer,但使用具有不同名称的MBean。您可以为这些MBean使用完全正交的域,或者添加类似额外的"限定符"除了其他属性之外,名称中的键值对。当我期望只有一个MBean用于典型情况时,我首先尝试添加具有固定名称的MBean。如果失败,我会在名称中添加另一个",qualifier=..."部分,其中包含一个自动生成的值,一个可以通过某个值(如WAR名称)唯一标识的值,或者甚至是可配置的值。

事实上,从客户角度来看,处理多个MBeanServers确实很痛苦,因此使用JMX作为具有唯一(可能是部分生成的MBean名称)的全局命名空间是一个简单的选项。