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 - 爱go,爱编程,专注网络开发,流媒体、分布式、网络加速,欢迎讨论listomebao@gmail.com

赞同来自: 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上你的应用就可以了。

要回复问题请先登录注册