我希望能够为在 heroku 上运行的 Java 应用程序生成 Java 线程转储?我看到 heroku 正在运行 jstack,但我不知道如何运行它以在我的进程上生成线程转储。我不知道如何让 PID 发送到 jstack。一旦我有了 PID,我只需从我的开发机器上运行“heroku jstack -l”(它安装了工具带)?
问问题
1046 次
3 回答
4
好的,这是最好的方法。这将为您提供 JVM 使用的格式,而不必以编程方式重新创建它。同样,这是针对 heroku 的,其他环境将需要调整此代码。这将其公开为一个休息接口。
@GET
@Transactional
@Path( "/threaddump" )
public Response threadDump() throws Exception {
dumpThreads();
return Response.ok().build();
}
public static void dumpThreads() throws Exception {
ProcessBuilder processBuilder = new ProcessBuilder( "/bin/sh", "-c", "kill -3 $PPID" );
processBuilder.redirectErrorStream( true );
Process process = processBuilder.start();
InputStream inputStream = process.getInputStream();
StreamUtils.copy( inputStream, System.out );
}
于 2013-05-15T20:17:37.297 回答
0
您可以尝试以下操作 - 将此函数放在某个类中并有办法调用它,将输出保存到文件或在页面上显示...
static StringBuilder allStack() {
StringBuilder sb = new StringBuilder();
Map<Thread, StackTraceElement[]> trace = Thread.getAllStackTraces();
for(Thread t:trace.keySet()){
StackTraceElement[]trc = trace.get(t);
sb.append("\n");
sb.append(t.getName());
sb.append(" ");
sb.append(t.getId());
sb.append(" |");
sb.append(t.getThreadGroup());
sb.append("| ");
sb.append(t);
sb.append(" :-\n");
for(StackTraceElement e:trc){
sb.append(e.toString());
sb.append("\n");
}
sb.append(" -***-\n");
}
return sb;
}
于 2013-05-11T20:37:49.813 回答
0
您还可以考虑将 REST API 嵌入到 java JMX 以执行此线程转储。Jolokia 似乎是一个不错的候选人。它还将支持内置身份验证并且更加灵活,因为您可以访问任何 JMX mbean 而无需实现新的 REST 端点
请参阅 http://www.jolokia.org ,特别是使用POST Exec 请求调用ThreadMXBean.dumpAllThreads()方法的 REST 协议
于 2014-03-07T11:15:00.217 回答