The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Nasser

关于 go gin 程序如果热更新的问题

  •  1
     
  •   Nasser · Sep 15, 2022 · 3898 views
    This topic created in 1365 days ago, the information mentioned may be changed or developed.

    大家好,请教一下 我准备使用 gin 来做后端 api 接口 但是在部署和热更新方案上比较困惑 应该怎样来实现 gin 程序的热更新呢 (还望大家不吝赐教)

    16 replies    2022-09-15 19:40:17 +08:00
    hdczsf
        1
    hdczsf  
       Sep 15, 2022
    不是有负载均衡吗,逐个重启更新节点,服务不会中断的.
    Nasser
        2
    Nasser  
    OP
       Sep 15, 2022
    @hdczsf gin 直接打包到服务器运行的,怎么重启不会导致服务重点呢?
    treblex
        3
    treblex  
       Sep 15, 2022
    https://github.com/fvbock/endless 优雅重启
    https://github.com/cosmtrek/air 外部工具,监控文件变动,重新编译

    需要配合使用
    moliliang
        4
    moliliang  
       Sep 15, 2022
    ```golang
    func runServer(addr string, engine *gin.Engine) error {
    server := &http.Server{
    Addr: addr,
    Handler: engine,
    WriteTimeout: 60 * time.Second,
    ReadTimeout: 60 * time.Second,
    }

    // 平滑关闭
    // 下面的 notify 是基于 signal.Notify 封装的,当监听到 kill ,会将 server shutdown
    notify.Subscribe(func() {
    timeoutCtx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()
    server.Shutdown(timeoutCtx)
    })

    return server.ListenAndServe()
    }
    ```

    上面的代码会监听 kill notify ,然后触发 shutdown ,shutdown 里面会停掉 listeners ,然后处理完所有已经连接的 socket 。

    理论上可以在启动新进程的时候,来给旧进程发送 kill ,旧进程挂掉,新进程启动监听端口就好啦
    Nasser
        5
    Nasser  
    OP
       Sep 15, 2022
    @treblex air 工具的文档上提示了:NOTE: This tool has nothing to do with hot-deploy for production.,不能用于生产环境
    yyttrr
        6
    yyttrr  
       Sep 15, 2022
    负载均衡加 k8s 的滚动部署策略
    lankunblue
        7
    lankunblue  
       Sep 15, 2022
    引入 k8s ?
    dzdh
        8
    dzdh  
       Sep 15, 2022
    endless 足够
    dzdh
        9
    dzdh  
       Sep 15, 2022
    reuseport 起新进程然后 kill 老服务
    Nasser
        10
    Nasser  
    OP
       Sep 15, 2022
    @lankunblue 小产品,不足以引入 k8s😂
    Nasser
        11
    Nasser  
    OP
       Sep 15, 2022
    @dzdh 好嘞,感谢,也是准备试试这个方案。
    SethShi
        12
    SethShi  
       Sep 15, 2022
    @Nasser
    单机器的话, 写个脚本部署自动部署到不同的端口, 然后 nginx -s reload 监听新端口, 停止旧服务
    多机器的话, 滚动更新就好了
    PungentSauce
        13
    PungentSauce  
       Sep 15, 2022
    @Nasser 官网有方案,写了用
    ```go
    routes.RegisterRoutes(engine)

    srv := &http.Server{
    Addr: ":" + port,
    Handler: engine,
    ReadTimeout: 10 * time.Second,
    WriteTimeout: 10 * time.Second,
    MaxHeaderBytes: 1 << 20,
    }
    logger.Info("Thousand-hand:listen " + port)
    fmt.Printf("use http://localhost:%s\n", port)

    go func() {
    if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
    log.Fatalf("listen: %s\n", err)
    }
    }()

    quit := make(chan os.Signal)
    signal.Notify(quit, os.Interrupt)
    _ = <-quit
    ```


    其实就是用一下 `quit := make(chan os.Signal)` 这个监听信号量 `endless ` 这个有点老了,已经好多年都不更新了,官网也写了
    `https://gin-gonic.com/zh-cn/docs/examples/graceful-restart-or-stop/`,而且如果你用的 1.8 以上,注意 1.8 不是 1.18 只要你用的版本不是很老很老的版本,你用信号量处理就好。这个是防止请求过程中出现重启的情况。
    xiaoz
        15
    xiaoz  
       Sep 15, 2022 via Android
    @Nasser #2 ,1 楼的意思是用了负载均衡的情况下,就是你后端启用了 2 个以上的服务。你在更新 A 的时候 B 依然可以提供服务,当 A 更新完毕后再更新 B ,这样最终完成所有后端服务的版本更新。但如果你后端是单机在跑的话就不太适合。
    a132811
        16
    a132811  
       Sep 15, 2022
    试下这个吧 reuseport+gracefulShutdown: https://github.com/jensneuse/GoGracefulReusePort
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5326 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 88ms · UTC 03:44 · PVG 11:44 · LAX 20:44 · JFK 23:44
    ♥ Do have faith in what you're doing.