go语言优雅关机和优雅重启条记

打印 上一主题 下一主题

主题 1724|帖子 1724|积分 5172

一、优雅关机



  • 生活化例子

    • 餐馆关门:你去餐馆吃暖锅,刚坐下点完菜(客户端发请求),餐馆老板忽然接到通知要停电(收到关机指令)。老板很知心,先停止欢迎新客人(停止吸收新请求),等你这桌和其他正在吃饭的客人(正在处理的请求)都吃完了,再关门走人。如许你的暖锅就能安安全全吃完,不会有任何丧失。

  • 代码示例
  1. package main
  2. import (
  3.         "context"
  4.         "log"
  5.         "net/http"
  6.         "os"
  7.         "os/signal"
  8.         "syscall"
  9.         "time"
  10.         "github.com/gin-gonic/gin"
  11. )
  12. func main() {
  13.         // 创建路由器
  14.         router := gin.Default()
  15.         router.GET("/cook-hotpot", func(c *gin.Context) {
  16.                 time.Sleep(5 * time.Second) // 模拟煮火锅需要时间
  17.                 c.String(http.StatusOK, "火锅煮好了,可以吃啦!")
  18.         })
  19.         // 创建服务器
  20.         srv := &http.Server{
  21.                 Addr:    ":8080",
  22.                 Handler: router,
  23.         }
  24.         // 在单独的goroutine中启动服务器
  25.         go func() {
  26.                 if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
  27.                         log.Fatalf("服务器监听错误: %s", err)
  28.                 }
  29.         }()
  30.         // 创建一个通道来接收系统信号
  31.         quit := make(chan os.Signal, 1)
  32.         signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) // 监听Ctrl+C和系统终止信号
  33.         // 阻塞等待信号
  34.         <-quit
  35.         log.Println("开始优雅关机...")
  36.         // 设置一个5秒超时的上下文
  37.         ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
  38.         defer cancel()
  39.         // 调用Shutdown方法优雅关闭服务器
  40.         if err := srv.Shutdown(ctx); err != nil {
  41.                 log.Fatalf("服务器优雅关机失败: %s", err)
  42.         }
  43.         log.Println("服务器已安全退出")
  44. }
复制代码


  • 验证结果

    • 运行上面的代码,启动服务。
    • 打开欣赏器访问 http://127.0.0.1:8080/cook-hotpot,模仿开始煮暖锅。
    • 在终端迅速实行 Ctrl+C 命令,向程序发送关机信号。
    • 观察程序不会立即退出,而是等待暖锅煮好(请求处理完)后才退出,实现优雅关机。

二、优雅重启



  • 生活化例子

    • 保安转班:小区门口有两名保安,保安A(老历程)正在值班,保安B(新历程)来接班。保安A不会直接走人,而是等手头的事(比如处理一辆正在进入的车)忙完,再让保安B接管工作。如许小区门口的秩序不会因为转班而受到影响。

  • 代码示例
  1. package main
  2. import (
  3.         "log"
  4.         "net/http"
  5.         "time"
  6.         "github.com/fvbock/endless"
  7.         "github.com/gin-gonic/gin"
  8. )
  9. func main() {
  10.         // 创建路由器
  11.         router := gin.Default()
  12.         router.GET("/greet", func(c *gin.Context) {
  13.                 time.Sleep(5 * time.Second) // 模拟处理请求需要时间
  14.                 c.String(http.StatusOK, "你好呀,欢迎来到小区!")
  15.         })
  16.         // 使用endless启动服务器,支持优雅重启
  17.         if err := endless.ListenAndServe(":8080", router); err != nil {
  18.                 log.Fatalf("服务器监听错误: %s", err)
  19.         }
  20.         log.Println("服务器已安全退出")
  21. }
复制代码


  • 验证结果

    • 编译并运行上述代码,终端会输出当前历程的 PID。
    • 修改代码中处理请求函数的返回值,如将 "你好呀,欢迎来到小区!" 修改为 "欢迎光临,小区新保安在此!",然后重新编译。
    • 打开欣赏器访问 http://127.0.0.1:8080/greet,模仿车辆进入小区。
    • 在终端迅速实行 kill -1 <ID> 命令,向程序发送优雅重启信号。
    • 等当前请求处理完(保安A处理完手头的事),再次访问时会收到新的欢迎语,说明在不影响当前请求的情况下完成了优雅重启,同时历程号也酿成了新的(保安B接班)。

三、总结



  • 优雅关机和优雅重启的焦点就是“有始有终”,不甩手不管正在做的事。
  • 优雅关机就像餐馆老板等你吃完暖锅再关门,通过监听系统信号(如Ctrl+C),调用Shutdown()方法,停止吸收新请求并等待现有请求处理完。
  • 优雅重启就像保安转班,使用endless库监听特定信号(如SIGHUP),启动新历程处理新请求,同时让老历程处理完现有请求再退出。
  • 在实际项目中,根据需求选择:需要安全关闭服务就用优雅关机;需要更新代码且不影响现网运行就用优雅重启。
自学go语言组件条记,希望我们可以一起学习!


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

嚴華

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表