用go来管理Java进程

时间:2016-03-10 01:53:29

标签: java linux go jvm

我已准备好JVM和Java程序的所有依赖项。使用Java,我会运行:

javac HelloWorld.java
java HelloWorld

现在我想在Linux环境中使用Go的cmd包来控制这个Java程序进程。在Go中,当您运行命令时,您将获得PID。有了这个PID,我希望每当j想要终止Java程序并使用相同的cmd包重启。只要我安装了JVM,这会正常工作吗?我想这样做:

cmd := exec.Command("bash", "-c", " "java HelloWorld")
cmd.Start()
syscall.Kill(cmd.Process.Pid)

谢谢!

1 个答案:

答案 0 :(得分:0)

简而言之,是的。

作为测试,添加了中断处理,因此您自己的Go进程不会终止,这将起作用:

package  main

import (
    "os/exec"
    "syscall"
    "os"
    "os/signal"
    "fmt"
)

func main()  {

    cmd := exec.Command("bash", "-c", "java HelloWorld")
    err := cmd.Start()
    fmt.Printf("Starting java proccess with pid %d\n", cmd.Process.Pid)
    if err != nil {
        // do something about it
    }

    c := make(chan os.Signal, 1)
    done := make(chan bool, 1)
    signal.Notify(c, os.Interrupt)
    signal.Notify(c, syscall.SIGTERM)

    go func() {
        <-c
        fmt.Printf("Sending interrupt to pid: %d\n", cmd.Process.Pid)
        syscall.Kill(cmd.Process.Pid, syscall.SIGHUP)
        done <- true
    }()
    <-done

}

Companion Java类:

public class HelloWorld {

    public static void main(String[] args) throws Exception {
        System.out.println("Hello World from Go! But you cant see me :)");
        while (true) {
            System.out.println("you cant see this because I am outing to the STDOUT of a subshell!");
            Thread.sleep(5000);
        }
    }
}

但它充满了陷阱。只要你的Go进程正常退出,它就会发送你指定的信号(sighup将是自然的选择,如果我冒险猜测)到java pid。但是你需要确保你不会让一个僵尸以防你自己的Go进程崩溃,或者你的java应用程序挂起后如果你告诉它没有干净地关闭。将pid保存到/ tmp /文件并在重启时执行各种操作可能会很有趣,但您知道自己的需求。

编辑:从另一个程序控制JVM进程可能会很快得到挑剔。你应该评估你是否真的想这样做。如果您使用的是Linux,请查看您的发行版使用的SysV init / systemd / upstart / start-stop-daemon系统,如果您的配套java程序充当守护程序。