From b0e5852800f73a93a1d7d207f5400fad78856c3a Mon Sep 17 00:00:00 2001 From: zhourui Date: Thu, 9 Jun 2022 10:37:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AE=9A=E6=97=B6thread=20du?= =?UTF-8?q?mp=20=E6=9B=B4=E6=96=B0ThreadDump,HeapDump?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../x/base/core/project/config/Config.java | 5 ++ .../com/x/server/console/StackTraceTask.java | 2 +- .../server/console/action/ActionControl.java | 6 +- .../com/x/server/console/action/HeapDump.java | 40 ++++++----- .../x/server/console/action/ThreadDump.java | 72 +++++++------------ 5 files changed, 55 insertions(+), 70 deletions(-) diff --git a/o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Config.java b/o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Config.java index 42d7d00945..a27dd39bf0 100644 --- a/o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Config.java +++ b/o2server/x_base_core_project/src/main/java/com/x/base/core/project/config/Config.java @@ -304,6 +304,11 @@ public class Config { return SystemUtils.IS_OS_WINDOWS ? dir.resolve("bin/jstack.exe") : dir.resolve("bin/jstack"); } + public static Path command_jmap_path() { + Path dir = Paths.get(System.getProperty("java.home")); + return SystemUtils.IS_OS_WINDOWS ? dir.resolve("bin/jmap.exe") : dir.resolve("bin/jmap"); + } + public static File dir_local() throws Exception { return new File(base(), DIR_LOCAL); } diff --git a/o2server/x_console/src/main/java/com/x/server/console/StackTraceTask.java b/o2server/x_console/src/main/java/com/x/server/console/StackTraceTask.java index f91b76313f..aa2c3408ea 100644 --- a/o2server/x_console/src/main/java/com/x/server/console/StackTraceTask.java +++ b/o2server/x_console/src/main/java/com/x/server/console/StackTraceTask.java @@ -32,7 +32,7 @@ public class StackTraceTask implements Job { String pid = Files.readString(Paths.get(Config.base(), "pid.log")); String file = Config.dir_logs().getAbsolutePath() + "/jstack_" + Config.node() + "_" + DateTools.format(now, DateTools.formatCompact_yyyyMMddHHmmss) + ".txt"; - String command = Config.command_jstack_path().toString() + " -l " + pid + " > " + file; + String command = Config.command_jstack_path().toString() + " -l -e " + pid + " > " + file; ProcessBuilder processBuilder = new ProcessBuilder(); if (SystemUtils.IS_OS_WINDOWS) { processBuilder.command("cmd", "/c", command); diff --git a/o2server/x_console/src/main/java/com/x/server/console/action/ActionControl.java b/o2server/x_console/src/main/java/com/x/server/console/action/ActionControl.java index c0afbf1a12..de3c30034b 100644 --- a/o2server/x_console/src/main/java/com/x/server/console/action/ActionControl.java +++ b/o2server/x_console/src/main/java/com/x/server/console/action/ActionControl.java @@ -151,8 +151,7 @@ public class ActionControl extends ActionBase { } private static Option tdOption() { - return Option.builder(CMD_TD).longOpt("threadDump").argName("count").optionalArg(true).hasArg() - .desc("服务器线程状态,间隔2秒.合并多次执行线程信息到最后一份日志.").build(); + return Option.builder(CMD_TD).longOpt("threadDump").hasArg(false).desc("生成线程转储文件.").build(); } private static Option ecOption() { @@ -243,9 +242,8 @@ public class ActionControl extends ActionBase { } private void td(CommandLine cmd) { - Integer count = this.getArgInteger(cmd, CMD_TD, 10); ThreadDump threadDump = new ThreadDump(); - threadDump.execute(count); + threadDump.execute(); } private void clh2(CommandLine cmd) throws Exception { diff --git a/o2server/x_console/src/main/java/com/x/server/console/action/HeapDump.java b/o2server/x_console/src/main/java/com/x/server/console/action/HeapDump.java index 13653437c5..b479bd63aa 100644 --- a/o2server/x_console/src/main/java/com/x/server/console/action/HeapDump.java +++ b/o2server/x_console/src/main/java/com/x/server/console/action/HeapDump.java @@ -1,35 +1,39 @@ package com.x.server.console.action; -import java.io.File; -import java.lang.management.ManagementFactory; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Date; -import javax.management.MBeanServer; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.SystemUtils; -import com.sun.management.HotSpotDiagnosticMXBean; import com.x.base.core.project.config.Config; import com.x.base.core.project.logger.Logger; import com.x.base.core.project.logger.LoggerFactory; import com.x.base.core.project.tools.DateTools; +import com.x.base.core.project.tools.DefaultCharset; public class HeapDump { - private static Logger logger = LoggerFactory.getLogger(HeapDump.class); + private static final Logger LOGGER = LoggerFactory.getLogger(HeapDump.class); - private static final String HOTSPOT_BEAN_NAME = "com.sun.management:type=HotSpotDiagnostic"; - - public void execute() throws Exception { + public void execute() { try { - Date start = new Date(); - File file = new File(Config.dir_logs(), - "heapDump_" + DateTools.format(start, DateTools.formatCompact_yyyyMMddHHmmss) + ".hprof"); - MBeanServer server = ManagementFactory.getPlatformMBeanServer(); - HotSpotDiagnosticMXBean bean = ManagementFactory.newPlatformMXBeanProxy(server, HOTSPOT_BEAN_NAME, - HotSpotDiagnosticMXBean.class); - bean.dumpHeap(file.getAbsolutePath(), true); - logger.print( - "generate java heap dump to {}, elapsed: {}ms, parses file see url: https://docs.oracle.com/javase/6/docs/technotes/tools/share/jhat.html", - file.getAbsoluteFile(), System.currentTimeMillis() - start.getTime()); + Date now = new Date(); + String pid = Files.readString(Paths.get(Config.base(), "pid.log")); + String file = Config.dir_logs().getAbsolutePath() + "/jmap_" + Config.node() + "_" + + DateTools.format(now, DateTools.formatCompact_yyyyMMddHHmmss) + ".hprof"; + String command = Config.command_jmap_path().toString() + " -dump:format=b,file=" + file + " " + pid; + ProcessBuilder processBuilder = new ProcessBuilder(); + if (SystemUtils.IS_OS_WINDOWS) { + processBuilder.command("cmd", "/c", command); + } else { + processBuilder.command("sh", "-c", command); + } + Process p = processBuilder.start(); + String resp = IOUtils.toString(p.getErrorStream(), DefaultCharset.charset_utf_8); + LOGGER.print("heap dump to {}.{}", file, resp); + p.destroy(); } catch (Exception e) { e.printStackTrace(); } diff --git a/o2server/x_console/src/main/java/com/x/server/console/action/ThreadDump.java b/o2server/x_console/src/main/java/com/x/server/console/action/ThreadDump.java index 19d952183b..8f6560b700 100644 --- a/o2server/x_console/src/main/java/com/x/server/console/action/ThreadDump.java +++ b/o2server/x_console/src/main/java/com/x/server/console/action/ThreadDump.java @@ -1,21 +1,17 @@ package com.x.server.console.action; -import java.lang.management.ManagementFactory; -import java.lang.management.RuntimeMXBean; -import java.nio.file.Path; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Date; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.SystemUtils; -import org.apache.commons.lang3.concurrent.BasicThreadFactory; import com.x.base.core.project.config.Config; import com.x.base.core.project.logger.Logger; import com.x.base.core.project.logger.LoggerFactory; import com.x.base.core.project.tools.DateTools; +import com.x.base.core.project.tools.DefaultCharset; /** * @@ -24,45 +20,27 @@ import com.x.base.core.project.tools.DateTools; */ public class ThreadDump { - private static Logger logger = LoggerFactory.getLogger(ThreadDump.class); - - public void execute(Integer count) { - - ExecutorService service = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), - new BasicThreadFactory.Builder().namingPattern(ThreadDump.class.getName()).daemon(true).build()); - - service.execute(() -> { - try { - RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean(); - String jvmName = runtimeBean.getName(); - long pid = Long.parseLong(jvmName.split("@")[0]); - Path path = SystemUtils.getJavaHome().toPath(); - if (null != path) { - path = path.getParent().resolve("bin/jcmd").toAbsolutePath(); - for (int i = 0; i < count; i++) { - Path out = Config.dir_logs(true).toPath() - .resolve("jcmd_Thread.print_" + pid + "_" - + DateTools.format(new Date(), DateTools.formatCompact_yyyyMMddHHmmss) + ".txt") - .toAbsolutePath(); - String cmd = path.toString() + " " + pid + " Thread.print >" + out.toString(); - ProcessBuilder processBuilder = new ProcessBuilder(); - if (SystemUtils.IS_OS_WINDOWS) { - processBuilder.command("cmd", "/c", cmd); - } else { - processBuilder.command("sh", "-c", cmd); - } - processBuilder.start(); - logger.print("thread dump to file:{}.", out.toString()); - Thread.sleep(1000); - } - logger.print("{} thread dump completed.", count); - } - } catch (InterruptedException e) { - logger.error(e); - Thread.currentThread().interrupt(); - } catch (Exception e) { - logger.error(e); + private static final Logger LOGGER = LoggerFactory.getLogger(ThreadDump.class); + + public void execute() { + try { + Date now = new Date(); + String pid = Files.readString(Paths.get(Config.base(), "pid.log")); + String file = Config.dir_logs().getAbsolutePath() + "/jstack_" + Config.node() + "_" + + DateTools.format(now, DateTools.formatCompact_yyyyMMddHHmmss) + ".txt"; + String command = Config.command_jstack_path().toString() + " -l -e " + pid + " > " + file; + ProcessBuilder processBuilder = new ProcessBuilder(); + if (SystemUtils.IS_OS_WINDOWS) { + processBuilder.command("cmd", "/c", command); + } else { + processBuilder.command("sh", "-c", command); } - }); + Process p = processBuilder.start(); + String resp = IOUtils.toString(p.getErrorStream(), DefaultCharset.charset_utf_8); + LOGGER.print("thread dump to {}.{}", file, resp); + p.destroy(); + } catch (Exception e) { + e.printStackTrace(); + } } } \ No newline at end of file -- GitLab