为什么 kill -15 不能优雅地杀死我的 Golang gRPC 服务?

问题描述

我使用信号处理程序来处理 SIGTERMSIGINT 信号。当 grpc 服务器启动并运行时,我发出 sudo kill -15 [PID] 命令,但我没有看到正常关机日志报告,而且我得到:

[1]    41983 terminated  go run mypkg/main.go

现在,当我使用 netstat 时,它报告端口号 50051 已打开,并且由于端口号繁忙,我无法运行我的服务器。

我做了什么:

func main() {
    flag.Parse()
    fmt.Printf("Starting up server on 0.0.0.0:%v...\n",*port)
    server := NewServer(fmt.Sprintf("0.0.0.0:%d",*port))
    wg := sync.WaitGroup{}
    wg.Add(1)
    go func() {
        server.Run()
        wg.Done()
    }()
    // Signal handling and graceful shutdown of gRPC server
    signalChan := make(chan os.Signal,1)
    signal.Notify(signalChan,syscall.SIGINT,syscall.SIGTERM)
    <-signalChan
    server.Stop()
    wg.Wait()
}

server.Stop() 函数用于停止 grpc 服务器,grpcServer.GracefulStop(),并记录一些数据。 当我发出 CTRL+C 时,一切都按预期工作。为什么在 sudo kill -15 我有这种行为?

解决方法

由于未来的读者可能也会遇到我的问题,我尝试根据用户评论回答我自己的问题。

彼得:

不要使用 go run。这种方式的信号转发可能不可靠。改用 go build 或 go install,或者至少不要杀死 -15 go 进程,而是杀死已经构建的二进制文件(可能是 /tmp 中的某些内容)。

吉姆:

我知道我们每天要说 100 次,但不要使用 go run(至少如果你不明白它在做什么的话)。当您从终端 ctrl+c 时,它会向整个进程组发送信号,而您并没有使用 kill 来执行此操作。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...