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

go 热更新的简单可行的解决方案

  •  1
     
  •   awanganddong · 2021-01-29 09:39:52 +08:00 · 6552 次点击
    这是一个创建于 1394 天前的主题,其中的信息可能已经有所发展或是发生改变。
    现在项目队列消费者打算用 go 来重构。

    现在问下 go 实现热更新的方式
    初期暂时不考虑 k8s 那套,有什么其他比较好的办法吗


    就是类似 nginx 热更新那样,起新的 work 进程来接替旧的 work 进程
    18 条回复    2021-02-01 09:31:01 +08:00
    monsterxx03
        1
    monsterxx03  
       2021-01-29 09:53:43 +08:00   ❤️ 1
    lewis89
        2
    lewis89  
       2021-01-29 10:33:08 +08:00
    热更新,运行中的线程 栈幁怎么处理?
    用新的二进制代码处理?新的二进制的代码能兼容老的栈幁结构?
    具体技术原理有什么介绍吗
    @monsterxx03
    lewis89
        3
    lewis89  
       2021-01-29 10:36:08 +08:00
    @monsterxx03 #1 看了..一下 nginx 用的是操作系统的提供进程信号 机制... 那这跟 k8s 流量切换本质上没什么区别..
    Vegetable
        4
    Vegetable  
       2021-01-29 10:46:22 +08:00   ❤️ 1
    nginx 是无状态的,但是应用程序可能是有状态的,fork 新程接管流量之后退出的方案是有的,比如 https://github.com/fvbock/endless
    如果想实现程序不停机维护,最简单的方法其实是双实例+负载均衡。不在代码层面做这个事了。
    fds
        5
    fds  
       2021-01-29 10:48:22 +08:00
    进程中的数据应该没法保留。毕竟底层没有个 VM 在运行。只能是交给第三方或者做个集群什么的。

    如果 socket 也要传递给新进程,可以参考 https://mosn.io/docs/concept/smooth-upgrade/ 通过 UNIX Domain Socket 传 fd 。
    另外还有个管理器可以参考,会下载新包重启的 https://github.com/jpillora/overseer
    rimutuyuan
        6
    rimutuyuan  
       2021-01-29 10:53:53 +08:00
    monsterxx03
        7
    monsterxx03  
       2021-01-29 10:55:05 +08:00   ❤️ 1
    README 里有个连接讲原理. 其实就是 nginx 那套, spawn 一个新的子进程加载 elf binary, 复制 fd, 接管新流量, 老的进程会等待一个 graceful timeout 的时间把已接收的请求处理完, 你是消息队列消费者的话就要确保 task 能在这个时间内被处理完否则会被强制 kill. 和 k8s 还是有区别的, k8s 是在 kube-proxy 那层完成的流量切换, 没这么 tricky, 功能更强(可以实现红绿部署).

    你说兼容栈帧那套单进程内热更新我很确定 go 是没有的,这个需要语言 runtime 支持, 印象里只有 erlang 支持, 而且限制性很大, 好处也就是能保留内存缓存.
    keepeye
        8
    keepeye  
       2021-01-29 10:55:23 +08:00
    印象中 go 好像没办法实现守护进程的
    monsterxx03
        9
    monsterxx03  
       2021-01-29 10:58:04 +08:00
    以为是楼主, 忘了 @lewis89
    siteshen
        10
    siteshen  
       2021-01-29 11:02:30 +08:00
    以前尝试过用代码完成热更新( API server ),但因为用 docker 运行会遇到了解决不了的问题而放弃。
    thet
        11
    thet  
       2021-01-29 11:27:27 +08:00
    前面加个 nginx
    Lonenso
        12
    Lonenso  
       2021-01-29 12:48:05 +08:00 via Android
    buffzty
        13
    buffzty  
       2021-01-29 13:07:56 +08:00
    为什么非要热更新 不中断服务无缝更新不行吗? nginx -> 2 个 upstream 先更新 1 更新完再更新 2 不是美滋滋?
    treblex
        14
    treblex  
       2021-01-29 13:08:01 +08:00
    endless 挺好的,需要写个脚本找一下旧的进程,然后 kill -SIGHUP endless 会根据 kill 信号 fork 进程
    现在都只用 air 了,发现文件变动自动重启,比热更新方便些
    vus520
        15
    vus520  
       2021-01-29 16:44:51 +08:00
    楼主是想实现长连接业务做无感升级?
    frozenshadow
        16
    frozenshadow  
       2021-01-29 17:11:49 +08:00 via Android
    mosn 里面有个通过 Unix socket,传递 accept fd 的骚操作
    2379920898
        17
    2379920898  
       2021-01-29 17:14:25 +08:00
    bee 了解一下
    awanganddong
        18
    awanganddong  
    OP
       2021-02-01 09:31:01 +08:00
    @buffzty 这个方案应该更适合我们的业务
    @vus520 应该是我理解有偏差了,直接用 nginx 切业务就可以了。

    谢谢大家了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1413 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 17:29 · PVG 01:29 · LAX 09:29 · JFK 12:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.