Platform MBean Server 的简单示例
假设我们有一些服务器注册新用户并用一些消息来问候它们。我们希望监控此服务器并更改其中的一些参数。
首先,我们需要一个与我们的监控和控制方法的接口
public interface UserCounterMBean {
long getSleepTime();
void setSleepTime(long sleepTime);
int getUserCount();
void setUserCount(int userCount);
String getGreetingString();
void setGreetingString(String greetingString);
void stop();
}
一些简单的实现将让我们看到它是如何工作的以及我们如何影响它
public class UserCounter implements UserCounterMBean, Runnable {
private AtomicLong sleepTime = new AtomicLong(10000);
private AtomicInteger userCount = new AtomicInteger(0);
private AtomicReference<String> greetingString = new AtomicReference<>("welcome");
private AtomicBoolean interrupted = new AtomicBoolean(false);
@Override
public long getSleepTime() {
return sleepTime.get();
}
@Override
public void setSleepTime(long sleepTime) {
this.sleepTime.set(sleepTime);
}
@Override
public int getUserCount() {
return userCount.get();
}
@Override
public void setUserCount(int userCount) {
this.userCount.set(userCount);
}
@Override
public String getGreetingString() {
return greetingString.get();
}
@Override
public void setGreetingString(String greetingString) {
this.greetingString.set(greetingString);
}
@Override
public void stop() {
this.interrupted.set(true);
}
@Override
public void run() {
while (!interrupted.get()) {
try {
System.out.printf("User %d, %s%n", userCount.incrementAndGet(), greetingString.get());
Thread.sleep(sleepTime.get());
} catch (InterruptedException ignored) {
}
}
}
}
对于本地或远程管理的简单示例,我们需要注册我们的 MBean:
import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
public class Main {
public static void main(String[] args) throws MalformedObjectNameException, NotCompliantMBeanException, InstanceAlreadyExistsException, MBeanRegistrationException, InterruptedException {
final UserCounter userCounter = new UserCounter();
final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
final ObjectName objectName = new ObjectName("ServerManager:type=UserCounter");
mBeanServer.registerMBean(userCounter, objectName);
final Thread thread = new Thread(userCounter);
thread.start();
thread.join();
}
}
之后我们可以运行我们的应用程序并通过 jConsole 连接到它,可以在你的 $JAVA_HOME/bin
目录中找到它。首先,我们需要使用我们的应用程序找到我们的本地 java 进程
然后切换到 MBeans 选项卡,找到我们在 Main 类中用作 ObjectName
的 MBean(在上面的例子中是 ServerManager
)。在 Attributes
部分,我们可以看到属性。如果仅指定了 get 方法,则属性将是可读的但不可写。如果同时指定了 get 和 set 方法,则属性将是可读写的。
可以在 Operations
部分中调用指定的方法。
如果你希望能够使用远程管理,则需要其他 JVM 参数,例如:
-Dcom.sun.management.jmxremote=true //true by default
-Dcom.sun.management.jmxremote.port=36006
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
这些参数可以在 JMX 指南的第 2 章中找到。之后,你将能够通过 jhsole 远程使用 jconsole host:port
或在 jConsole GUI 中指定 host:port
或 service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi
连接到你的应用程序。
有用的链接: