[英]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)
幾個問題
我覺得這是連接到不同的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控制台,因為我打算手動完成所有操作,以實現自動化。
好吧,我弄清楚我做錯了什么。 最初我試圖將值檢索為
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.