为了账号安全,请及时绑定邮箱和手机立即绑定

使用 go 管理 Java 进程

使用 go 管理 Java 进程

Go
汪汪一只猫 2021-12-20 16:32:27
我已准备好 JVM 和 Java 程序的所有依赖项。使用 Java 我会像这样运行:javac HelloWorld.javajava 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 回答

?
慕田峪9158850

TA贡献1794条经验 获得超7个赞

简而言之,是的。


作为测试,添加中断处理,因此您自己的 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


}

配套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,如果您的配套 java 程序充当守护程序,我会查看您的发行版使用的 SysV init/systemd/upstart/start-stop-daemon 系统。


查看完整回答
反对 回复 2021-12-20
  • 1 回答
  • 0 关注
  • 267 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信