golang gin graceful shutdown

更新日期: 2023-06-28 阅读次数: 752 字数: 327 分类: golang

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