博客
关于我
Golang 平滑重启之优雅关机
阅读量:641 次
发布时间:2019-03-13

本文共 1822 字,大约阅读时间需要 6 分钟。

前言

作为一个web服务,在构建过程中升级操作总是不可避免的,而在此之前,优雅地关闭服务则是另一个关键步骤。对于传统的编程环境而言,直接暴力终止进程虽然能快速启动新服务,但在业务敏感的场景下显然不适用。幸运的是,Go语言在1.8版本及以后对http服务器的支持,为我们提供了一种更优雅的解决方案。

一、Shutdown机制

在Go中,http.Server的Shutdown方法能够帮助我们优雅地终止服务器。这个方法的工作原理是,当检测到中断信号(如Ctrl+C或 SIGTERM)时,会阻止新的请求进入服务器,同时保持现有的连接状态,直到所有处理完成后,程序才会正式退出。这种机制非常适合在需要长时间处理请求的业务场景中使用。

二、使用步骤

以下将通过一个基于Gin框架的实际案例,详细说明如何在Go中实现服务器的优雅关闭。

案例说明

var i = 0  func main() {      router := gin.Default()      // 创建两个路由:一个处理延迟请求,一个处理立即响应      router.GET("/", func(c *gin.Context) {          time.Sleep(9 * time.Second)          i++          c.JSON(http.StatusOK, gin.H{              "num": i,          })      })      router.GET("/a", func(c *gin.Context) {          i++          c.JSON(http.StatusOK, gin.H{              "num": i,          })      })      srv := &http.Server{          Addr:    ":8080",          Handler: router,      }      // 在后台启动服务器,避免阻塞优雅关闭      go func() {          if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {              log.Fatalf("listen: %s\n", err)          }      }()      //监听终止信号      quit := make(chan os.Signal, 1)      signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)      si <- quit      log.Println("Shutting down server...", si)      // 进行优雅关闭      ctx, cancel := context.WithCancel(context.Background())      defer cancel()      if err := srv.Shutdown(ctx); err != nil {          log.Fatal("Server forced to shutdown:", err)      }      log.Println("Server exiting")  }

代码解释

  • 创建路由:使用Gin框架创建了两个路由,分别处理延迟请求和立即响应。
  • 启动服务器:将服务器启动在后台 goroutine 中,以避免阻塞优雅关闭的处理。
  • 监听终止信号:通过信号通道监听终止信号(如Ctrl+C),当检测到信号时,触发优雅关闭流程。
  • 优雅关闭:使用 context.WithCancel 创建上下文,传递给 srv.Shutdown 方法。
  • 处理错误:如果在关闭过程中遇到错误,记录日志并退出程序。
  • 优势分析

    • 非阻塞:优雅关闭不会阻塞当前处理的请求,确保业务能够正常完成。
    • 可靠性:即使在中断时也能保证服务器优雅退出,避免数据丢失或服务崩溃。
    • 灵活性:支持带时间限制和无时间限制的关闭方式,适用于不同的业务场景。

    通过上述方法,我们可以在Go中实现服务器的优雅关闭,确保服务的平稳升级和维护。

    转载地址:http://dwyoz.baihongyu.com/

    你可能感兴趣的文章
    Nginx配置参数中文说明
    查看>>
    Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
    查看>>
    Nginx配置如何一键生成
    查看>>
    Nginx配置实例-负载均衡实例:平均访问多台服务器
    查看>>
    NHibernate学习[1]
    查看>>
    NIFI1.21.0_Mysql到Mysql增量CDC同步中_日期类型_以及null数据同步处理补充---大数据之Nifi工作笔记0057
    查看>>
    NIFI1.21.0_NIFI和hadoop蹦了_200G集群磁盘又满了_Jps看不到进程了_Unable to write in /tmp. Aborting----大数据之Nifi工作笔记0052
    查看>>
    NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增删改数据分发及删除数据实时同步_通过分页解决变更记录过大问题_02----大数据之Nifi工作笔记0054
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
    查看>>
    NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
    查看>>
    NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
    查看>>
    Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
    查看>>
    NIFI大数据进阶_离线同步MySql数据到HDFS_02_实际操作_splitjson处理器_puthdfs处理器_querydatabasetable处理器---大数据之Nifi工作笔记0030
    查看>>
    NIFI大数据进阶_连接与关系_设置数据流负载均衡_设置背压_设置展现弯曲_介绍以及实际操作---大数据之Nifi工作笔记0027
    查看>>
    NIFI数据库同步_多表_特定表同时同步_实际操作_MySqlToMysql_可推广到其他数据库_Postgresql_Hbase_SqlServer等----大数据之Nifi工作笔记0053
    查看>>
    NIFI汉化_替换logo_二次开发_Idea编译NIFI最新源码_详细过程记录_全解析_Maven编译NIFI避坑指南001---大数据之Nifi工作笔记0068
    查看>>
    NIFI集群_内存溢出_CPU占用100%修复_GC overhead limit exceeded_NIFI: out of memory error ---大数据之Nifi工作笔记0017
    查看>>
    NIFI集群_队列Queue中数据无法清空_清除队列数据报错_无法删除queue_解决_集群中机器交替重启删除---大数据之Nifi工作笔记0061
    查看>>
    NIH发布包含10600张CT图像数据库 为AI算法测试铺路
    查看>>
    Nim教程【十二】
    查看>>