Golang 杂谈 - graceful shutdown 为何离奇失效?
事情是发生在一个夜黑风高的晚上,同事偶然间发现一个一直在跑的服务的日志有点奇怪,退出处理日志有概率出现,感觉`graceful shutdown`像是失效了一样,无独有偶,第二天早上刚好有报错日志,我一查,初步怀疑是因为没有成功graceful shutdown导致的。Emmm。。。。这么诡异嘛!
实际上graceful shutdown的大致实现没什么,因为本身就是一个worker独自处理逻辑数据的服务,只要确定退出前把当前的任务处理完就会,任务本身的传递是用队列解耦了,一点堆积无伤大雅。所以实际上就是用signal包里的`Notify`函数监听一下退出信号,收到后,执行完任务后通过channel退出程序而已。
那么问题来了,这部分graceful shutdown的逻辑就是在入口模块而已,实际上我们基本都没怎么改动过,最多是在功能模块上有所变更之类的,怎么也不可能改到这里。那么这时候就要开始排查:
先复现一下?
基本能复现,收到signal后的代码是有概率执行的。
咋看之下代码没改动,是不是环境或者go版本不一样?
编译的go版本最近的确有更新,但实现了一波,环境和版本都没问题
那看起来还是代码问题,查看下程序的exit status
是0,看起来是程序自身的正常退出,这时候就可以查一下代码里哪里有os.exit了,结果一搜发现居然是在引用的库内。。。因为signal的notify是都可以接收到的,所以库里面刚好也有接收,并且执行了exit。
万万没想到是这种原因,虽说那个库本身并不是作为三方库使用,但代码这么写的确是不大好的。。。后续修改掉之后便恢复正常了。
版权声明: 本文为 InfoQ 作者【星语】的原创文章。
原文链接:【http://xie.infoq.cn/article/a60b4c8363ac2e34e323f8de5】。文章转载请联系作者。
评论