golang使用endless优雅重启发生"use of closed network connection"错误
在使用 github.com/fvbock/endless
对web服务进行优雅重启时,error 会返回错误
server closed :accept tcp [::]:8005: use of closed network connection
在实际使用过程中, 程序是被成功重启的, 但是这一行错误究竟是否由某种问题引发? 是否跟运行环境有关? 一直不太清楚。
今天有幸在掘金读到一篇文章详细排查这个问题 Beego框架的一条神秘日志引发的思考
虽然文中是以 Beego 使用过程中进行描述的,但是内部原因是一致的。源码上的内容由于暂时能力有限,很难解读,但是从结论上还是很清晰的。
启动服务之后,是一个经典的 Listen + Accept 结构, 会新建一个协程执行 Accept 并阻塞。(关于 Listen + Accept ,可以查阅这篇文章 Go语言TCP Socket编程)
当我们开始优雅重启时, 父进程会Fork出一个子进程,Fork的时候会把自己的套接字以参数形式给到子进程, 当子进程也开启服务进行 Listen + Accept 后,会通过管道给父进程信号,父进程会处理完请求之后自我结束。 之后子进程会变为父进程。
关键来了,当我们的父进程的其中一个协程,处于 Accept 堵塞状态中,此时我们进行优雅重启,由于父进程的Socket已经给了新的进程, 这个堵塞的 Accept 永远都不会接收到新的数据,从而报错。
所以从这个流程上来看, 这个报错其实是可以被理解的,我们程序上可以对其进行忽略。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。