繁体   English   中英

Tomcat JMX - 连接到服务器但无法找到我想要的MBean

[英]Tomcat JMX - Connecting to server but cant find the MBean i want

我正在尝试编写一个客户端实用程序,通过JMX连接到Tomcat并查看连接数据源的状态。 我在$ CATALINA_HOME / bin / setenv.bat中设置了以下VM参数,并重新启动了Tomcat

设置JAVA_OPTS = -Xms512M -Xmx1024M -XX:MaxPermSize = 256M%JAVA_OPTS%设置CATALINA_OPTS = -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port = 9004 -Dcom.sun.management.jmxremote.authenticate = false -Dcom.sun.management.jmxremote.ssl = false%CATALINA_OPTS%

我对JMX不是很熟悉所以我只是想玩它来感受它。 我写的实用程序将在Tomcat之外运行。 我编写了以下测试来尝试访问Tomcat中的数据源Mbean对象,但由于某种原因它没有找到它。

    public class GuiMonitor {
      public static void main(String[] args){

       try{
        JMXServiceURL url = new JMXServiceURL(
             "service:jmx:rmi:///jndi/rmi://localhost:9004/jmxrmi");
            JMXConnector jmxc = JMXConnectorFactory.connect(url, null);

            final List<MBeanServer> servers = new LinkedList<MBeanServer>();

            servers.add(ManagementFactory.getPlatformMBeanServer());
            servers.addAll(MBeanServerFactory.findMBeanServer(null));

            System.out.println("MbeanServers " + servers.size()); 

            for(final MBeanServer server : servers){
              System.out.println("Server : " + server.getClass().getName());
             }

            MBeanServer mbsc = ManagementFactory.getPlatformMBeanServer();
            System.out.println(mbsc.queryMBeans(null, null));
            ObjectName on = new ObjectName("Catalina:type=DataSource,path=/appdb,host=localhost,class=javax.sql.DataSource,name=\"jdbc/appdb\"");
            System.out.println("ObjectName : " + on.toString());
            System.out.println(mbsc.getAttribute(on, "Catalina:type=DataSource,path=/appdb,host=localhost,class=javax.sql.DataSource,name=\"jdbc/appdb\""));

       } catch (Exception e) {
                 e.printStackTrace();
             }  
          }
         }

我有一个我在互联网上找到的JSP页面,当我上传到webapps文件夹并运行它时,它会显示Tomcat中所有可用的MBean。 我上面使用的对象字符串/名称来自我使用的jsp页面和Jconsole上报告的名称,因此它确实存在。

上述程序的输出如下所示

     MbeanServers 2

     Server : com.sun.jmx.mbeanserver.JmxMBeanServer
     Server : com.sun.jmx.mbeanserver.JmxMBeanServer

     [com.sun.management.OperatingSystem[java.lang:type=OperatingSystem], sun.management.MemoryPoolImpl[java.lang:type=MemoryPool,name=Tenured Gen], sun.management.MemoryPoolImpl[java.lang:type=MemoryPool,name=Perm Gen], java.util.logging.Logging[java.util.logging:type=Logging], sun.management.CompilationImpl[java.lang:type=Compilation], javax.management.MBeanServerDelegate[JMImplementation:type=MBeanServerDelegate], sun.management.MemoryImpl[java.lang:type=Memory], sun.management.MemoryPoolImpl[java.lang:type=MemoryPool,name=Survivor Space], sun.management.RuntimeImpl[java.lang:type=Runtime], sun.management.GarbageCollectorImpl[java.lang:type=GarbageCollector,name=Copy], sun.management.MemoryPoolImpl[java.lang:type=MemoryPool,name=Eden Space], sun.management.GarbageCollectorImpl[java.lang:type=GarbageCollector,name=MarkSweepCompact], sun.management.ThreadImpl[java.lang:type=Threading], sun.management.MemoryPoolImpl[java.lang:type=MemoryPool,name=Perm Gen [shared-ro]], sun.management.MemoryPoolImpl[java.lang:type=MemoryPool,name=Perm Gen [shared-rw]], sun.management.HotSpotDiagnostic[com.sun.management:type=HotSpotDiagnostic], sun.management.ClassLoadingImpl[java.lang:type=ClassLoading], sun.management.MemoryManagerImpl[java.lang:type=MemoryManager,name=CodeCacheManager], sun.management.MemoryPoolImpl[java.lang:type=MemoryPool,name=Code Cache]]
     ObjectName : Catalina:type=DataSource,path=/appdb,host=localhost,class=javax.sql.DataSource,name="jdbc/appdb"

     javax.management.InstanceNotFoundException: Catalina:type=DataSource,path=/appdb,host=localhost,class=javax.sql.DataSource,name="jdbc/appdb"
      at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getMBean(DefaultMBeanServerInterceptor.java:1094)
      at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:662)
      at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:638)
      at com.bt.c21.c21mon.C21GuiMonitor.main(C21GuiMonitor.java:39)

几个问题

  • 网址是否正确? 我知道端口号是正确的,但我不确定服务名称。 我在URL上使用的服务名称“jmxrmi”只是我在其中一个我看过的例子中看到的。

我觉得这是连接到不同的MBeanServer。 我怀疑这是因为如果你看一下mbsc.queryMBeans(null,null)的输出,就没有特定的tomcat。 我用于Tomcat实例的服务名称是什么?

  • 如果URL正确,那么服务名称是否总是jmxrmi? 为什么它找不到“Catalina:type = DataSource,path = / appdb,host = localhost,class = javax.sql.DataSource,name = \\”jdbc / appdb \\“”条目?

  • 我已经看到很多如何做到这一点的例子,大多数使用不同的方法来获取MbeanServer。 我见过几个例子

    ManagementFactory.getPlatformMBeanServer()MBeanServerFactory.findMBeanServer(null)getMBeanServerConnection()

  • 如前所述,我正在编写的实用程序是一个普通的java应用程序,它将在tomcat之外运行。 我有没有错过任何其他配置? 我一直在看几个例子,大多数人都在谈论创建MBean,并且通常会引用Listeners。 由于我没有创建任何新的Mbeans但只读取现有的值,我是否需要配置一个监听器?

编辑

似乎getPlatformMbeanServer()没有返回正确的JVM实例。 我尝试了以下内容

MBeanServerConnection conn = jmxc.getMBeanServerConnection(); 
System.out.println("Query2  : " + conn.queryMBeans(null, null)); 

这确实返回了一些Tomcat特定的值。 但我仍然无法获得jdbc / appdb数据源。

krtek - 我无法使用JMX控制台,因为我打算手动完成所有操作,以实现自动化。

编辑2

好吧,我弄清楚我做错了什么。 最初我试图将值检索为

MBeanServerConnection conn = jmxc.getMBeanServerConnection(); 
ObjectName on = new ObjectName("Catalina:type=DataSource,path=/appdb,host=localhost,class=javax.sql.DataSource,name=\"jdbc/appdb\"");
mbsc.getAttribute(on, "Catalina:type=DataSource,path=/appdb,host=localhost,class=javax.sql.DataSource,name=\"jdbc/appdb\""));

以上是错误的,因为mbsc.getAttribute的第二个参数应该是Mbean中的属性而不是String名称。

这给了我正确的属性值

MBeanServerConnection conn = jmxc.getMBeanServerConnection(); 
ObjectName on = new ObjectName("Catalina:type=DataSource,path=/appdb,host=localhost,class=javax.sql.DataSource,name=\"jdbc/appdb\"");
mbsc.getAttribute(on, "numIdle")

我还将我从getPlatformMbeanServer()使用的MBeanServer更改为getMBeanserverConnection()。 我必须承认我不太了解其中的区别,因为Tomcat与getPlatformMbeanServer()返回的JVM运行在同一个JVM上。 这是否意味着getPlatformMbeanServer()只返回特定于Sun的Mbeans? 和getMBeanserverConnection()将包括两者?

谢谢

那是因为您正在为您的客户端JVM获取JMX服务器的实例,而不是Tomcat实例。

这是对的:

JMXServiceURL url = new JMXServiceURL(
    "service:jmx:rmi:///jndi/rmi://localhost:9004/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);

但你应该继续这样的事情:

MBeanServerConnection conn = jmxc.getMBeanServerConnection(); 
Set result = conn.queryMBeans(null, 
"Catalina:type=DataSource,path=/appdb,host=localhost,class=javax.sql.DataSource");

要测试查询字符串,请使用JMX控制台等工具。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM