go语言gin、net/http的优雅关机

本文介绍HTTP服务器优雅关机的概念及其实现方法。优雅关机能够确保在服务器关闭前完成所有正在处理的请求,避免数据不一致的问题。文章详细解释了如何使用net/http库中的srv.Shutdown方法来实现这一目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是优雅关机?

http-server运行过程中,若进程被关闭,那么正在处理的请求可能只被处理了一半就停止了,可能会产生数据的不一致。

优雅关机是指:

  • 首先,停止接收新请求;
  • 然后,等待队列中的请求被处理完毕;
  • 最后,应用程序退出;

net/http原生的shutdown函数支持优雅关机。

优雅关机的实现

首先,在goroutine中启动http-server:

srv := &http.Server{
  Addr:              ":8090",
  Handler:           r,
}
go func() {
  if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
     log.Fatal("listen: ", err)
  } else {
       log.Println("ListenAndServe break")
  }
}()

然后,在main中监听关机信号:

  • SIGTERM: kill的默认信号;
  • SIGINT:kill -2,一般是Ctrl+C的退出;
  • SIGKILL:kill -9,捕获不到;
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<- quit

net/http优雅关机的实现原理
优雅关机是调用net/http的srv.Shutdown(ctx)实现的,该方法会:

  • 先拒绝后面的connection请求;
  • 然后再慢慢的处理未处理完毕的请求;
  • 当未处理的请求一旦被处理完毕,其connection变成Idle,然后被Close()掉;
func (srv *Server) Shutdown(ctx context.Context) error {
    ...
    for _, f := range srv.onShutdown {
       go f()
    }
    ...

    ticker := time.NewTicker(shutdownPollInterval)
    defer ticker.Stop()
    for {
       if srv.closeIdleConns() {    //关闭idle连接
          return lnerr
       }
       select {
           case <-ctx.Done():       //ctx到期,如cancel()被调用
              return ctx.Err()
           case <-ticker.C:
       }
    }
}

另外,当调用Shutdown()后,srv.ListenAndServer方法将退出,并返回ErrServerClose错误。

参考链接

优雅地关机或重启

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

辛集电子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值