golang gin graceful shutdown

文章目录

    在做一个微信支付的流程,担心经常更新程序导致服务中断,影响退款等逻辑,所以想加上 graceful shutdown 功能。

    参考 Golang Gin 官方文档:

    https://gin-gonic.com/docs/examples/graceful-restart-or-stop/

    使用 Go 1.8 之后内置的 http.Server Shutdown() 方法,以实现 graceful shutdowns。

    测试

    // 测试 graceful shutdown
    // /api/testSleep?duration=20s
    func TestSleep(c *gin.Context) {
    	duration := c.DefaultQuery("duration", "") // /api?arg=N
    	duration2, err := time.ParseDuration(duration)
    
    	if err != nil {
    		c.JSON(http.StatusOK, gin.H{
    			"err_code": 1,
    			"err_msg":  "invalid duration",
    		})
    		return
    	}
    
    	log.Println("start sleeping")
    	time.Sleep(duration2)
    	log.Printf("end sleeping from pid %d.\n", os.Getpid())
    
    	c.JSON(http.StatusOK, gin.H{
    		"err_code": 0,
    		"err_msg":  "OK",
    	})
    }
    

    浏览器里访问:

    http://localhost:9999/api/testSleep?duration=20s
    

    测试结果

    但是测试并不符合预期:

    2023/06/27 14:59:40 start sleeping
    ^C2023/06/27 14:59:43 Shutdown Server ...
    2023/06/27 14:59:48 Server Shutdown:context deadline exceeded
    

    服务是在 ctrl c 之后 5 秒就强行结束了,并没有等待处理完。

    但也有好的方面:

    • 确实是新的请求进不来,并且运行中的处理不超时的情况下,会处理完。倒是可以接收,如果改成 10 秒,确实已经可以规避 99.99% 的问题了。
    • systemctl stop 也会等待完全退出之后,才返回,非常好。

    TODO

    我感觉 gin 官方给的这个示例有问题,在找找其他的实现吧。

    参考

    • https://gin-gonic.com/docs/examples/graceful-restart-or-stop/
    • https://juejin.cn/post/7015911395413721118

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式