【发布时间】:2019-09-11 20:25:19
【问题描述】:
我有一个 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() 之后的语句通常不会执行。如果 closeDbConnections() 被执行,一些 DbConnections 将被关闭。
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 来测试后一种情况。
有人可以解释一下这种行为吗?
【问题讨论】:
-
您没有提供问题代码的示例,但如果您没有等待您的 goroutine 在
main中返回,您将在程序完成之前退出程序。 -
@JimB goroutine 只是在运行服务器,
main直到GracefulStop完成才返回,所以我看不出有问题。 @agyeya,回答你的问题,不需要时间。当main返回时(在函数结束时),进程退出。 -
@Adrian:他们说“这很好用”,这是我们似乎没有的非工作案例。这听起来像是基本的“goroutines 之前的主要退出”问题。
-
哦,我明白你在说什么 - 是的,这将是假设(但未显示)代码中的问题。
-
添加了有问题的代码。只是想了解它的问题,我的用例对其他代码感到满意
标签: go server grpc goroutine grpc-go