golang写的web application 怎么优雅的更新?

像php这种解释型语言开发的web application ,更新代码的时候都是直接push就可以了,不会中断服务,但是像golang这种编译型的语言更新完代码还要编译

我的问题是怎么在不中断服务的前提下更新golang web application?通常的做法有哪些?还请各位不吝赐教

已邀请:

raindylong - 学习go的路上,盼望登顶的一天

赞同来自: astaxie sujunxuan cholerae 小浩 CurveSoft

一般的做法都是在webapp前加一层nginx之类的,由nginx的upsteam group搞定灰度更新的问题,例如可新、旧版本webapp同时工作一段时间,稳定后去掉旧版本只留新版本,如此类推。

以上。

astaxie - 创造、获取、分享、传播和应用Go

赞同来自: 小浩 Anjie CurveSoft

web application基本上都是短连接的应用,所以采用Nginx的upsteam是更好的方式

sheepbao - https://sheepbao.github.io 爱go,爱编程,领域网络开发,流媒体、分布式、网络加速

赞同来自: sujunxuan RedMothball

可以用golang自己实现,但是只在类unix系统中有用,利用系统信号量和启动子进程,将旧的socket描述符传递给新的socket描述符,github已经有不少这样的库,很多golang的http框架也实现了。这种实现叫“graceful restart”或者“zero downtime server”,实现不中断服务更新。 具体参考可以看看这些项目和几篇文章:

kevin - 杭州云柚科技

赞同来自:

利用graceful restart,更新二进制文件后发送指令重启服务器

songtianyi

赞同来自:

1楼正解,补充一下,灰度更新可以用openresty,国人的热门项目。

tsingson

赞同来自:

首先, 肯定一下 nginx 方法比较成熟, 配置简单.

不过, 我用更简单的方法, 只适用于 macOS / linux :

package main

import (
    "fmt"
    "github.com/kavu/go_reuseport"
    "golinksmart/config"
    "golinksmart/handler"
    "runtime"
)

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    // 使用 reuseport 进行连接监听, 以便使用 taskset 来绑定 CPU
    listener, err := reuseport.Listen("tcp", config.Configuration.Server.AaaPort)
    if err != nil {
        panic(err)
    }

    //interrupt := make(chan os.Signal, 1)
    //signal.Notify(interrupt, os.Interrupt, os.Kill, syscall.SIGTERM)

    handler.AaaServer(listener)
    fmt.Println("AAA listening on ", config.Configuration.Server.AaaPort)
    /**
    for {
        select {
        case killSignal := <-interrupt:
            fmt.Println("Got signal:", killSignal)
            fmt.Println("Stoping listening on ", listener.Addr())
            listener.Close()
        }
    }
    */

}

代码见上面, 其中这个 handler.AaaServer(listener) 其实是下面代码的封装 http.Serve(listener, router)

由于对端口侦听是 reuseport 所以, go 的 http server 可以运行多个实例, 只要更新其中某一个就完成灰度更新了.

stirlingx - https://github.com/liyue201

赞同来自:

一般都是集群了啊,杀一个重启一个

maxwell92 - Kubernetes Go

赞同来自:

用Kubernetes对外提供服务,起多个实例,然后用CI/CD系统每次的提交都打成镜像,那么每次你做的事情就是:推代码然后滚动升级Kubernetes上你的应用就可以了。

要回复问题请先登录注册