Skip to content

Commit

Permalink
vjtop 用命令行指定JMX端口 #82
Browse files Browse the repository at this point in the history
  • Loading branch information
calvin1978 committed Aug 14, 2018
1 parent 5356a94 commit 8fd71cd
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 18 deletions.
17 changes: 15 additions & 2 deletions vjtop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,14 +222,27 @@ ERROR: Could not attach to process.
```


1. 执行vjtop的用户,对/tmp/.java_pid$PID 文件有读写权限,该文件权限为srw------- 1,所以需要相同用户或root权限用户 sudo执行。
1. 执行vjtop的用户,对/tmp/.java_pid$PID 文件有读写权限,该文件权限为srw------- 1,所以需要相同用户

2. /tmp/.java_pid$PID 文件再首次连接时会生成,但如果生成之后被/tmp 目录的清理程序错误删除,JVM将不再能连入,只能重启应用。
2. /tmp/.java_pid$PID 文件在首次连接时会生成,但如果生成之后被/tmp 目录的清理程序错误删除,JVM将不再能连入,只能重启应用。

3. 目标JVM使用启动参数-Djava.io.tmpdir,重定向了tmp目录路径

4. 目标JVM使用启动参数-XX:+DisableAttachMechanism禁止了attach

如果实在没有办法attach,可以考虑在原目标进程中配置JMX启动参数,设定JMX的地址与端口,然后在vjtop中指定

目标进程的JVM参数:
```
-Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.port=7001 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.X=false -Dcom.sun.management.jmxremote.ssl=false
```

vjtop的命令(since 1.0.3):

```
./vjtop.sh -j 127.0.0.1:7001 <PID>
```


# 4. 改进点

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ private void changeThreadLimit() {
if (threadLimit != app.view.threadLimit) {
app.view.threadLimit = threadLimit;
if (app.nextFlushTime() > 1) {
tty.println(" Number of threads to display changed to " + threadLimit + "for next flush ("
tty.println(" Number of threads to display changed to " + threadLimit + " for next flush ("
+ app.nextFlushTime() + "s later)");
}
} else {
Expand Down
13 changes: 10 additions & 3 deletions vjtop/src/main/java/com/vip/vjtools/vjtop/VJTop.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ private static OptionParser createOptionParser() {
parser.acceptsAll(Arrays.asList(new String[] { "l", "limit" }),
"Number of threads to display ( default to 10 threads)").withRequiredArg().ofType(Integer.class);

parser.acceptsAll(Arrays.asList(new String[] { "j", "jmxurl" }),
"JMX url like 127.0.0.1:7001 when VM attach is not work").withRequiredArg().ofType(String.class);

// detail mode
parser.accepts("cpu",
"default mode in detail view, display thread cpu usage and sort by thread delta cpu time ");
Expand All @@ -59,7 +62,6 @@ private static OptionParser createOptionParser() {

public static void main(String[] args) {
try {

// 1. create option parser
OptionParser parser = createOptionParser();
OptionSet optionSet = parser.parse(args);
Expand All @@ -72,9 +74,14 @@ public static void main(String[] args) {
// 2. create vminfo
String pid = parsePid(parser, optionSet);

VMInfo vminfo = VMInfo.processNewVM(pid);
String jmxHostAndPort = null;
if (optionSet.hasArgument("jmxurl")) {
jmxHostAndPort = (String) optionSet.valueOf("jmxurl");
}

VMInfo vminfo = VMInfo.processNewVM(pid, jmxHostAndPort);
if (vminfo.state != VMInfoState.ATTACHED) {
System.out.println("\nERROR: Could not attach to process, please find reason in README\n");
System.out.println("\nERROR: Could not attach to process, see the solution in README\n");
return;
}

Expand Down
6 changes: 3 additions & 3 deletions vjtop/src/main/java/com/vip/vjtools/vjtop/VMInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ private VMInfo() {
/**
* 创建JMX连接并构造VMInfo实例
*/
public static VMInfo processNewVM(String pid) {
public static VMInfo processNewVM(String pid, String jmxHostAndPort) {
try {
final JmxClient jmxClient = new JmxClient(pid);
jmxClient.connect();
final JmxClient jmxClient = new JmxClient();
jmxClient.connect(pid, jmxHostAndPort);

// 注册JMXClient注销的钩子
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
Expand Down
27 changes: 18 additions & 9 deletions vjtop/src/main/java/com/vip/vjtools/vjtop/data/jmx/JmxClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ public class JmxClient {

private String pid;

private JMXServiceURL jmxUrl = null;
private MBeanServerConnection mbsc = null;
private SnapshotMBeanServerConnection server = null;
private JMXConnector jmxc = null;
Expand All @@ -81,8 +80,7 @@ public class JmxClient {
private JmxMemoryPoolManager memoryPoolManager = null;
private JmxBufferPoolManager bufferPoolManager = null;

public JmxClient(String pid) throws IOException {
this.pid = pid;
public JmxClient() throws IOException {
}

public void flush() {
Expand All @@ -91,13 +89,24 @@ public void flush() {
}
}

public void connect() throws Exception {
public void connect(String pid, String jmxHostAndPort) throws Exception {
this.pid = pid;

if (jmxHostAndPort != null) {
JMXServiceURL jmxUrl = new JMXServiceURL(
"service:jmx:rmi://" + jmxHostAndPort + "/jndi/rmi://" + jmxHostAndPort + "/jmxrmi");
Map credentials = new HashMap(1);
String[] creds = new String[] { null, null };
credentials.put(JMXConnector.CREDENTIALS, creds);

// 如果jmx agent未启动,主动attach进JVM后加载
String address = attachToGetConnectorAddress();
this.jmxc = JMXConnectorFactory.connect(jmxUrl, credentials);
} else {
// 如果jmx agent未启动,主动attach进JVM后加载
String address = attachToGetConnectorAddress();

this.jmxUrl = new JMXServiceURL(address);
this.jmxc = JMXConnectorFactory.connect(jmxUrl);// NOSONAR
JMXServiceURL jmxUrl = new JMXServiceURL(address);
this.jmxc = JMXConnectorFactory.connect(jmxUrl);// NOSONAR
}

this.mbsc = jmxc.getMBeanServerConnection();
this.server = Snapshot.newSnapshot(mbsc);
Expand Down Expand Up @@ -230,7 +239,7 @@ private ObjectName createBeanName(String beanName) {

@Override
public String toString() {
return pid;
return "JMX Client for PID:" + pid;
}

/**
Expand Down

0 comments on commit 8fd71cd

Please sign in to comment.