2

我希望能够为在 heroku 上运行的 Java 应用程序生成 Java 线程转储?我看到 heroku 正在运行 jstack,但我不知道如何运行它以在我的进程上生成线程转储。我不知道如何让 PID 发送到 jstack。一旦我有了 PID,我只需从我的开发机器上运行“heroku jstack -l”(它安装了工具带)?

4

3 回答 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 回答