連接配接器概念:
JMX規範定義了連接配接器的概念(Connectors),連接配接器位于JMX的3層構架中的分布式服務層。連接配接器負責建立MBean伺服器和管理應用之間的通信。連接配接器由一個駐留在代理層的連接配接器伺服器(connector server)和管理應用的連接配接器用戶端(connector client)構成。連接配接器服務端(connector server)連接配接到MBean伺服器并監聽來自用戶端(connector client)的請求。一個connector client負責與connector server建立連接配接。connnector client通常與connector server在不同的JVM裡并且通常運作在不同的機器上。
1.連接配接器類型(Connector type)
connnector client通過給定協定與connector server建立連接配接,遠端通路MBean伺服器。JMX API允許使用不同類型的連接配接器來連接配接MBean伺服器。
* JMX API定義了一個标準連接配接器 - RMI Connector,它支援通過RMI協定遠端通路一個MBeanServer
* JMX API定義了一個可選的連接配接器 - JMXMP Connector.它實作了JMXMP協定(JMX Message Protocol).作為一個可選連接配接器,它不內建在JavaSE平台中,若需要,從Sun官方 下載下傳jar
* 使用者自定義連接配接器協定
2.連接配接器伺服器位址
通常,一個connector server有一個位址,由類JMXServiceURL表示,這個類的執行個體是不可變的。使用不同的連接配接器,會有不同的JMXServiceURL編寫方式。
格式看起來如下:
service:jmx:protocol:sap
說明:
service:jmx: 這個是JMX URL的标準字首,所有的JMX URL都必須以該字元串開頭。
protocol是指定連接配接連接配接器伺服器(connector server)的傳輸協定
方括号中的部分為可選部分
sap是連接配接器伺服器的位址,sap的文法格式://[host[:port]][url-path]
host表示主機名,port是十進制的端口号
host和port可以省略,但沒有host時,不能出現port
url-path 開始于一個"/"符号
參考JMX API : http://docs.oracle.com/javase/8/docs/api/index.html?javax/management/remote/rmi/package-summary.html
參考:http://www.l99.com/EditText_view.action?textId=480750
3. RMI連接配接器
JMX API定義了一個标準連接配接器 - RMI Connector,它支援通過RMI遠端通路一個MBeanServer
RMI連接配接器伺服器的位址示例如下:
service:jmx:rmi://localhost:1099/jndi/rmi://localhost:8899/myname
說明:
在這個JMXServiceURL中,第一個rmi指的是rmi連接配接器,表示用連接配接器使用RMI傳輸協定,第二個rmi指定RMI注冊RMI連服務接器存儲存根
localhost:1099: 這個是connector server的IP和端口,該部分是一個可選項,可以被省略掉。如果省略的話,則connector server會随機任意選擇一個可用的端口
/jndi/rmi://localhost:8899/myname: 這個是connector server的路徑,表示Connector server的stud是使用JNDI API綁定在rmi://localhost:8899/myname這個位址上
建立一個RMI connector server
通常是提供一個RMI connector server的連接配接器位址,用JMXConnectorServerFactory.newJMXConnectorServer方法來建立RMI connector cerver
參考JMX API:http://docs.oracle.com/javase/8/docs/api/index.html?javax/management/remote/rmi/package-summary.html
下面是使用RMI連接配接器遠端管理程式的例子:
Step 1.MBean接口定義
package com.jmx.demo9;
import java.io.Serializable;
public interface HelloMBean extends Serializable {
public void setName(String name);
public String getName();
public void sayHello();
}
Step 2.MBean接口實作類
package com.jmx.demo9;
import java.io.Serializable;
public class Hello implements HelloMBean, Serializable {
private String name;
public synchronized void setName(String name) {
this.name = name;
}
public synchronized String getName() {
return name;
}
public synchronized void sayHello() {
System.out.println("Hello," + name);
}
}
Step 3.服務端
package com.jmx.demo9;
import java.rmi.registry.LocateRegistry;
import java.util.HashMap;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectInstance;
import javax.management.ObjectName;
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import javax.security.auth.Subject;
public class JMXAgent {
/**
* @param args
* the command line arguments
*/
public static void main(String[] args) throws Exception {
System.out.println("--------------JMX Agent----------- ");
LocateRegistry.createRegistry(1099);
MBeanServer server = MBeanServerFactory.createMBeanServer();
ObjectName helloName = new ObjectName("com.jmx.demo9:name=Hello");
Hello hello = new Hello();
HashMap<String, Object> prop = new HashMap<String, Object>();
prop.put(JMXConnectorServer.AUTHENTICATOR, new JMXAuthenticator() {
public Subject authenticate(Object credentials) {
if (credentials instanceof String) {
if (credentials.equals("Hello")) {
return new Subject();
}
}
throw new SecurityException("not authicated");
}
});
JMXConnectorServer cserver = JMXConnectorServerFactory
.newJMXConnectorServer(new JMXServiceURL(
"service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi"),
prop, server);
cserver.start();
server.registerMBean(hello, helloName);
for (ObjectInstance object : server.queryMBeans(null, null)) {
System.out.println(object.getObjectName());
}
System.out.println(hello);
System.out.println("start.....");
System.out.println("\n");
}
}
note:ObjectName對象辨別符命名規則參考JMX API:http://docs.oracle.com/javase/8/docs/api/javax/management/ObjectName.html
Step 4.用戶端(管理應用程式)
package com.jmx.demo9;
import java.util.HashMap;
import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class Client {
public static void main(String[] args) throws Exception {
HashMap<String, Object> prop = new HashMap<String, Object>();
prop.put(JMXConnector.CREDENTIALS, "Hello");
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
JMXConnector conn = JMXConnectorFactory.connect(url, prop);
MBeanServerConnection mbsc = conn.getMBeanServerConnection();
ObjectName mbeanName = new ObjectName("com.jmx.demo9:name=Hello");
HelloMBean hello = JMX.newMBeanProxy(mbsc, mbeanName,HelloMBean.class);
hello.setName("World!");
hello.sayHello();
}
}
測試結果:
先啟動JMXAgent,在啟動Client
--------------JMX Agent-----------
JMImplementation:type=MBeanServerDelegate
com.jmx.demo9:name=Hello
[email protected]
start.....
Hello,world