我有一个 gRPC 服务器,并且我已经实现了 gRPC 服务器的正常关闭,就像这样
fun main() {
//Some code
term := make(chan os.Signal)
go func() {
if err := grpcServer.Serve(lis); err != nil {
term <- syscall.SIGINT
}
}()
signal.Notify(term, syscall.SIGTERM, syscall.SIGINT)
<-term
server.GracefulStop()
closeDbConnections()
}
这工作正常。相反,如果我在主 goroutine 中编写grpcServer.Serve()
逻辑,而是将关闭处理程序逻辑放入另一个 goroutine,server.GracefulStop()
则通常不会执行之后的语句。某些 DbConnections 已关闭,如果closeDbConnections()
完全执行。
server.GracefulStop()
是阻塞调用。绝对grpcServer.Serve()
在完成之前server.GracefulStop()
完成。那么,这个调用返回后,main goroutine 需要多长时间才能停止呢?
有问题的代码
func main() {
term := make(chan os.Signal)
go func() {
signal.Notify(term, syscall.SIGTERM, syscall.SIGINT)
<-term
server.GracefulStop()
closeDbConnections()
}()
if err := grpcServer.Serve(lis); err != nil {
term <- syscall.SIGINT
}
}
这种情况没有按预期工作。完成后server.GracefulStop()
,closeDbConnections()
可能会运行也可能不会运行(通常不会运行到完成)。我通过从终端按 Ctrl-C 发送 SIGINT 来测试后一种情况。
有人可以解释这种行为吗?