[zeromicro/go-zero]使用了zrpc client的服务,在收到SIGTERM信号后为什么也需要走gracefulStop方法?以及gracefulStop方法的实现是否不太合理?

2024-03-05 879 views
2

按我理解,zrpc server端在收到SIGTERM信号时,确实需要走gracefulStop方法安全退出 但由于client.go和server.go同在package zrpc下,所以同样会调用到core/proc的init()方法,同样会监听信号。这里是不是稍微不太合理?

image

而且gracefulStop()方法在实现上,貌似也有点问题:

func gracefulStop(signals chan os.Signal) {
    signal.Stop(signals)

    logx.Info("Got signal SIGTERM, shutting down...")
    wrapUpListeners.notifyListeners()

    time.Sleep(wrapUpTime)
    shutdownListeners.notifyListeners()

    time.Sleep(delayTimeBeforeForceQuit - wrapUpTime)
    logx.Infof("Still alive after %v, going to force kill the process...", delayTimeBeforeForceQuit)
    syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
}

这里看起来是,收到SIGTERM之后,会关闭所有的listener,然后sleep几秒,然后再给自己发一个SIGTERM 所以理论上这个方法执行结束之前,程序都不会正式退出 但sleep几秒之后,日志中却提示still alive,给人的感觉就是程序异常了,没有正常退出 这里是不是不太合理?

回答

8

不能只理论上,你实测一下就知道了

5

作为初学者,问个小白问题。 为啥我kill -15后,日志打印了“Got signal SIGTERM, shutting down...”,但是程序貌似被直接关了,并没有执行完毕 我的程序里就一开始sleep了5秒,然后打印一句话 kill -15后,优雅下线是不是打印的那句话还是应该打印出来?

1

贴代码哈

2

作为初学者,问个小白问题。 为啥我kill -15后,日志打印了“Got signal SIGTERM, shutting down...”,但是程序貌似被直接关了,并没有执行完毕 我的程序里就一开始sleep了5秒,然后打印一句话 kill -15后,优雅下线是不是打印的那句话还是应该打印出来?

贴代码哈

企业微信截图_603cd829-28e0-4a0d-9cb3-4c4d67efc80c
企业微信截图_d0a76109-a612-4c5e-920b-42e4de0346ca
1

sleep5秒只是为了我能在调用加密后的瞬间有时间kill -15,我理解的应该也会打印out才对呀

5

可运行代码贴出来,我跑了重现下问题哈

5

我只是用了goctl生成了代码框架,在logic的代码中加了一条sleep和一条log。 是不是我kill的姿势不对? 我是先go build这个rpc,然后nohup ./killtest -f rpc/etc/killtest.yaml & 通过ps找到了pid,然后kill -15 pid nohup的日志里5432在slow的状态下打印了,但output没有打出来

killTest.tar.gz nohup.txt

3

我也有疑惑,在执行完kill命令后,服务只是打印了“Got signal SIGTERM, shutting down... 没有继续打印 “Still alive after %v, going to force kill the procee...” 这行日志

3

我已经直到了,就是 notifyListeners 方法一执行 waitGroup.Done() 方法就调用 外部的主程中的waitGroup.Wait()不在等待 主程结束,这个协程中后续代码就不执行了