簡體   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