V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
imherer
V2EX  ›  程序员

大佬们 go 更新版本的时候文件锁怎么解决的?

  •  
  •   imherer · 2018-12-19 09:43:17 +08:00 · 2486 次点击
    这是一个创建于 2184 天前的主题,其中的信息可能已经有所发展或是发生改变。
    “文件锁” 这个词不知道用的准不准确,我也是在别处听说的

    现在有这么一个场景:

    假如我用 go 写了一个 web 服务,当需要版本更新的时候需要替换当前服务器的文件,但是必须得停掉服务才能上传更新,而且 go 编译出来的文件还挺大的,上传到服务器所需时间几秒到几十秒不等

    像 Python、Node.js ,它更新是直接可以上传覆盖的,需要重启服务后更新的才生效,而这个重启时间很短,1s 不到,用户那端几乎是无感知的

    大佬们是如何解决的呢?
    18 条回复    2018-12-19 13:17:59 +08:00
    0987363
        1
    0987363  
       2018-12-19 09:48:29 +08:00 via Android   ❤️ 1
    上传到缓存目录,然后停止服务,然后替换,然后启动服务,用脚本一次性搞定
    ikaros
        2
    ikaros  
       2018-12-19 09:48:40 +08:00   ❤️ 1
    你先上传到 home 下面,然后 mv 过去覆盖源程序,然后 supervisor restart 一下也就不到 1s 吧?
    Aliencn
        3
    Aliencn  
       2018-12-19 09:50:40 +08:00   ❤️ 1
    1 楼说的适用于 Windows 和 Linux 系统。
    2 楼说的适用于 Linux 系统。
    misaka19000
        4
    misaka19000  
       2018-12-19 09:53:45 +08:00   ❤️ 2
    最好的做法当然是起多个服务进程然后依次更新以此来保证服务不会中断
    ck65
        5
    ck65  
       2018-12-19 09:57:06 +08:00 via iPhone   ❤️ 1
    ELB。单机不可能确保没有 downtime。
    pkookp8
        6
    pkookp8  
       2018-12-19 10:01:34 +08:00 via Android   ❤️ 1
    mv 到临时目录
    kill 原进程
    启动临时目录进程
    cp 到原目录覆盖
    kill 临时进程
    启动原目录进程

    linux 可以省略前三步,因为 linux 不存在运行的进程文件不能操作的问题
    yuikns
        7
    yuikns  
       2018-12-19 10:02:40 +08:00 via iPhone   ❤️ 1
    docker 直接顶掉不就行了?
    reus
        8
    reus  
       2018-12-19 10:08:30 +08:00   ❤️ 1
    上传时用另外的名字,不要直接覆盖,上传完了,再 mv
    gamexg
        9
    gamexg  
       2018-12-19 10:15:46 +08:00
    linux 即使程序运行着也可以删除、改名。
    windows 下即使运行着也是可以改名。
    zhengxiaowai
        10
    zhengxiaowai  
       2018-12-19 10:58:52 +08:00
    一般来说有些语言支持热替换的比如 erlang,python 通过 hack 方式也能支持。

    对于一般情况来说,如果你部署了多实例,用 nginx 反代的话,可以几个几个重启更新,nginx 会自己打到正常的服务下面,现在 docker 都是那么做的。如果你是单实例,那么 build 好之后,关闭当前重启新服务也是很快的
    zjsxwc
        11
    zjsxwc  
       2018-12-19 11:01:40 +08:00
    nginx 灰度发布+1
    kappa
        12
    kappa  
       2018-12-19 11:04:05 +08:00
    loveCoding
        13
    loveCoding  
       2018-12-19 11:04:52 +08:00
    负载均衡 + 持续集成 ,比较有代表性的就是 nginx + jenkins .完全没锁的概念
    fcten
        14
    fcten  
       2018-12-19 11:07:02 +08:00
    用软连接启动,更新服务后修改软连接的地址然后重启。

    想要完全无缝的话就用 nginx 反代。
    qiyuey
        15
    qiyuey  
       2018-12-19 11:10:09 +08:00 via Android
    这是典型的平滑发布问题,无论替换多快总会有空洞期,热替换局限性比较大,正确做法是部署前主动进行当前机器的服务下线,部署成功后主动进行当前机器的服务上线。
    ChristopherWu
        16
    ChristopherWu  
       2018-12-19 11:25:48 +08:00
    最好的应该是:
    旧的 A 程序 与 旧的 B 程序同时运行,nginx 的 upstream 改对应的后端,reload。
    AlphaTr
        17
    AlphaTr  
       2018-12-19 11:56:04 +08:00 via iPhone
    关键词 Graceful Restart,有很多实现的
    cholerae
        18
    cholerae  
       2018-12-19 13:17:59 +08:00
    服务发现加滚动更新加优雅退出?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   934 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 22:49 · PVG 06:49 · LAX 14:49 · JFK 17:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.