Golang中优雅的重启Web服务
在项目实际运行过程中,如果只有单机器,不考虑红黑发布等应用,代码更新迭代重新打包后,必须考虑平滑重启的问题。
平常开发过程中,都是直接粗暴的使用 CTRL+C 进行手动重启,这明显不能直接应用到生产环境中,这会导致服务中断。
这时可以使用 github.com/fvbock/endless
,他可以通过接收信号,处理完请求后再进行优雅重启。
https://github.com/fvbock/endless
# 安装
go get github.com/fvbock/endless
代码示例,配合使用Gin
package main
import (
"net/http"
"time"
"github.com/fvbock/endless"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/get", func(c *gin.Context) {
time.Sleep(time.Second * 5)
c.JSON(http.StatusOK, gin.H{
"hi": "23334",
})
})
endless.ListenAndServe(":8001", r)
}
加入 time.Sleep()
是为了直观的体现出平滑重启的能力, 重启过程中不会中断服务, 请求会正常被处理。
go build
出程序后, 运行, 访问 localhost:8001/get
, 等待5秒会返回JSON。
{"hi":"23334"}
直接修改程序中的 23334
为 233345
, 重新 go build
打包。 使用 ps
找出上一个运行程序的PID,
先再次访问 localhost:8001/get
, 然后命令行中操作重启
sudo kill -SIGHUP xxx
最后API中会返回
{"hi":"23334"}
再次访问 localhost:8001/get
后, 则会返回出最新改动
{"hi":"233345"}
重启过程中, 程序也会返回出相关信息
2021/11/26 17:13:01
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /get --> main.main.func1 (3 handlers)
2021/11/26 17:13:01 18580 :8001
2021/11/26 17:13:01 18509 Received SIGTERM.
2021/11/26 17:13:01 18509 Waiting for connections to finish...
2021/11/26 17:13:01 18509 [::]:8001 Listener closed.
[GIN] 2021/11/26 - 17:13:04 | 200 | 5.0052797s | ::1 | GET "/get"
2021/11/26 17:13:04 18509 Serve() returning...
[GIN] 2021/11/26 - 17:13:14 | 200 | 5.005136313s | ::1 | GET "/get"
github.com/fvbock/endless
本身还支持其他信号,具体使用可以看文档,这里只简单介绍平滑重启的应用。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。