在做一个微信支付的流程,担心经常更新程序导致服务中断,影响退款等逻辑,所以想加上 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 聊聊, 查看更多联系方式