V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
Nasser
V2EX  ›  Go 编程语言

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

  •  1
     
  •   Nasser · 2022-09-15 16:10:53 +08:00 · 3111 次点击
    这是一个创建于 833 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    需要配合使用
    moliliang
        4
    moliliang  
       2022-09-15 16:28:38 +08:00
    ```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
       2022-09-15 16:53:58 +08:00
    @treblex air 工具的文档上提示了:NOTE: This tool has nothing to do with hot-deploy for production.,不能用于生产环境
    yyttrr
        6
    yyttrr  
       2022-09-15 16:59:10 +08:00
    负载均衡加 k8s 的滚动部署策略
    lankunblue
        7
    lankunblue  
       2022-09-15 17:10:26 +08:00
    引入 k8s ?
    dzdh
        8
    dzdh  
       2022-09-15 17:13:11 +08:00
    endless 足够
    dzdh
        9
    dzdh  
       2022-09-15 17:13:30 +08:00
    reuseport 起新进程然后 kill 老服务
    Nasser
        10
    Nasser  
    OP
       2022-09-15 17:22:09 +08:00
    @lankunblue 小产品,不足以引入 k8s😂
    Nasser
        11
    Nasser  
    OP
       2022-09-15 17:22:34 +08:00
    @dzdh 好嘞,感谢,也是准备试试这个方案。
    seth19960929
        12
    seth19960929  
       2022-09-15 18:03:09 +08:00
    @Nasser
    单机器的话, 写个脚本部署自动部署到不同的端口, 然后 nginx -s reload 监听新端口, 停止旧服务
    多机器的话, 滚动更新就好了
    PungentSauce
        13
    PungentSauce  
       2022-09-15 18:07:42 +08:00
    @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 只要你用的版本不是很老很老的版本,你用信号量处理就好。这个是防止请求过程中出现重启的情况。
    ryalu
        14
    ryalu  
       2022-09-15 18:21:27 +08:00
    xiaoz
        15
    xiaoz  
       2022-09-15 18:50:49 +08:00 via Android
    @Nasser #2 ,1 楼的意思是用了负载均衡的情况下,就是你后端启用了 2 个以上的服务。你在更新 A 的时候 B 依然可以提供服务,当 A 更新完毕后再更新 B ,这样最终完成所有后端服务的版本更新。但如果你后端是单机在跑的话就不太适合。
    a132811
        16
    a132811  
       2022-09-15 19:40:17 +08:00
    试下这个吧 reuseport+gracefulShutdown: https://github.com/jensneuse/GoGracefulReusePort
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5312 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 07:53 · PVG 15:53 · LAX 23:53 · JFK 02:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.