Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在heroku上为Java进程生成线程转储?_Java_Heroku - Fatal编程技术网

如何在heroku上为Java进程生成线程转储?

如何在heroku上为Java进程生成线程转储?,java,heroku,Java,Heroku,我希望能够为运行在heroku上的java应用程序生成java线程转储?我看到heroku正在运行jstack,但我不知道如何运行它在我的进程上生成线程转储。我不知道如何将PID发送到jstack。一旦我有了PID,我只需从我的开发机器上运行“heroku jstack-l”(它安装了toolbelt)?您可以尝试以下操作-将此函数放在某个类中,并有方法调用它,将输出保存到文件或在页面上显示它 static StringBuilder allStack() { StringBuilder

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

您可以尝试以下操作-将此函数放在某个类中,并有方法调用它,将输出保存到文件或在页面上显示它

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;
}
静态StringBuilder allStack(){
StringBuilder sb=新的StringBuilder();
Map trace=Thread.getAllStackTraces();
对于(线程t:trace.keySet()){
StackTraceElement[]trc=trace.get(t);
某人附加(“\n”);
sb.append(t.getName());
某人加上(“”);
sb.append(t.getId());
某人加上(“|”);
sb.append(t.getThreadGroup());
某人加上(“|”);
某人附加(t);
sb.追加(“:-\n”);
用于(StackTraceElement e:trc){
某人附加(如toString());
某人附加(“\n”);
}
sb.追加(“-***-\n”);
}
归还某人;
}

您可以尝试以下操作-将此函数放入某个类中,并有方法调用它,将输出保存到文件或在页面上显示它

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;
}
静态StringBuilder allStack(){
StringBuilder sb=新的StringBuilder();
Map trace=Thread.getAllStackTraces();
对于(线程t:trace.keySet()){
StackTraceElement[]trc=trace.get(t);
某人附加(“\n”);
sb.append(t.getName());
某人加上(“”);
sb.append(t.getId());
某人加上(“|”);
sb.append(t.getThreadGroup());
某人加上(“|”);
某人附加(t);
sb.追加(“:-\n”);
用于(StackTraceElement e:trc){
某人附加(如toString());
某人附加(“\n”);
}
sb.追加(“-***-\n”);
}
归还某人;
}

好的,下面是最好的方法。这将为您提供JVM使用的格式,而不必以编程方式重新创建它。同样,这是为了heroku,其他环境将需要调整此代码。这将其公开为rest接口

@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 );
}

好的,这是最好的方法。这将为您提供JVM使用的格式,而不必以编程方式重新创建它。同样,这是为了heroku,其他环境将需要调整此代码。这将其公开为rest接口

@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 );
}

您也可以考虑将REST API嵌入到java JMX中来执行这个线程转储。约洛基亚似乎是个不错的候选人。它还将支持内置身份验证,并且更加灵活,因为您可以访问任何JMX mbean,而无需实现新的REST端点


尤其是使用

调用方法的REST协议,您也可以考虑将REST API嵌入到java JMX中来执行这个线程转储。约洛基亚似乎是个不错的候选人。它还将支持内置身份验证,并且更加灵活,因为您可以访问任何JMX mbean,而无需实现新的REST端点


特别是使用

调用方法的REST协议。谢谢,我知道怎么做。但我不想以编程的方式来做。我想在控制台上做。因此,对于在Heroku dyno上运行的web服务器,我想从本地机器生成一个线程转储。不知道。如果进程被挂起,它将更强大。为什么不在你的主人那里买张票呢?谢谢,我知道怎么做。但我不想以编程的方式来做。我想在控制台上做。因此,对于在Heroku dyno上运行的web服务器,我想从本地机器生成一个线程转储。不知道。如果进程被挂起,它将更强大。为什么不在您的主机中通过票证提问?是org.springframework.util.StreamUtils吗?什么是响应类型?为什么不将输出写入文件?只是好奇。我理解kill-3部分,但想知道为什么你会选择这种方法来获得回复。我想把它写在我的书面记录中,我也想让它像Ctrl-Break一样回复。我真的不想把它归档。我不确定我是否理解你关于回复类型的问题。在StreamUtils上,您还可以使用Guava CharStreams.toString(in)并将其发送到函数public Response threadDump()中的LOG或System.out{,这个响应类的全名是什么?我不熟悉。所以这会将结果打印到应用程序系统中?哦,我只是在使用JAX-RS Jersey。这是他们拥有的一个响应类。是org.springframework.util.StreamUtils吗?响应类型是什么?为什么不将输出写入文件?只是好奇。我理解kill-3的b部分我想知道你为什么选择这种方法来获取回复。我希望它出现在我的书面记录中,我也希望它能像Ctrl-Break一样响应。我不希望它出现在文件中。我不确定我是否理解你关于回复类型的问题。在StreamUtils上,你也可以使用Guava CharStreams.toString(in)在你的函数中,public Response threadDump()抛出异常{,这个响应类的全名是什么?我不太熟悉。所以这会将结果打印到应用程序系统输出?哦,我只是在使用JAX-RS Jersey。这是他们的响应类。