V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
twogoods
V2EX  ›  程序员

服务如何做到平滑升级?

  •  
  •   twogoods · 2018-07-27 19:45:02 +08:00 · 6731 次点击
    这是一个创建于 2312 天前的主题,其中的信息可能已经有所发展或是发生改变。

    例如一个服务两个实例,前面 nginx 负载均衡。

    nginx 可以做到实时的健康监测吗?一旦一个服务 kill 不往这个服务上转发请求,不过这样好像还是有一个问题,我要升级必然要 kill 掉一个服务,kill 瞬间如果还有请求在这个实例里,那么这个请求就无法返回数据,这样用户感知到异常了。 所以最好的方式是要重启一个服务前,告诉负载均衡器不要转发请求到我这里,然后等一段时间等这个机器上所有请求都处理完,这个时候老的请求完毕,新的请求不过来,就可以更新重启。

    nginx 下有这样的功能吗? haproxy 下倒是有 agent check 可以实现这个功能。

    21 条回复    2018-07-28 18:25:04 +08:00
    feverzsj
        1
    feverzsj  
       2018-07-27 19:56:35 +08:00
    draining 功能只在收费版中有
    veelog
        2
    veelog  
       2018-07-27 19:59:41 +08:00 via iPhone
    nginx 有个 next_stream 就是这个用吧
    swulling
        3
    swulling  
       2018-07-27 20:09:06 +08:00
    一般都在服务这里做 graceful shutdown

    如果服务这里不太好做,那么其实有一个比较简单的方法,就是每一个服务实例前面再套一个 nginx,每次 shutdown 的时候,先 graceful shutdown 这个 nginx,然后再杀服务。

    我司有些产品线就是这么做的,把每个服务实例都绑一个 nginx,好处除了这个外,还自动就有了标准的监控、日志等等,较大的降低了服务改造成本。
    ChristopherWu
        4
    ChristopherWu  
       2018-07-27 20:11:22 +08:00
    @veelog 没有查到任何关于 next_stream 的资料
    veelog
        5
    veelog  
       2018-07-27 20:23:25 +08:00 via iPhone
    理解错了楼主的意思,next_stream 是描述当一个服务出现该配置描述的异常后,自动切到下一个服务,这个还不满足楼主的要求
    veelog
        6
    veelog  
       2018-07-27 20:25:36 +08:00 via iPhone
    楼主要求的功能,我可以试试后端服务不要直接 kill 掉,而是发一个信号,后端服务关闭监听的端口,这样新的连接不会过来了
    misaka19000
        7
    misaka19000  
       2018-07-27 20:29:55 +08:00 via Android
    当一台负载要下线了,先通知 nginx 此台负载下线,nginx 不再向此台负载转发请求,之后此台负载把当前进程的任务全部做完后在停止进程。上线的时候就很简单了,先上线再通知 nginx 就可以了
    veelog
        8
    veelog  
       2018-07-27 20:30:25 +08:00 via iPhone
    @ChristopherWu next_upstream
    greatbody
        9
    greatbody  
       2018-07-27 21:03:18 +08:00
    如果是 java 等语言的话,可以考虑 controller 都继承一个鸡肋,这个鸡肋负责监听关闭信号,收到关闭信号后,就不再继续接收请求,只完成现有的请求。然后所有的已开始请求都处理完成后,自动退出。

    这个是理论上的想法。
    fengdianxun
        10
    fengdianxun  
       2018-07-27 21:11:06 +08:00 via Android
    熔断器?
    hash
        11
    hash  
       2018-07-27 21:29:29 +08:00
    @greatbody 输入法好评 /手动笑哭
    rrfeng
        12
    rrfeng  
       2018-07-27 21:32:00 +08:00
    nginx 开源版可以配置 max_fails + next_upstream 勉强做到,但不平滑。因为是以几次错误的尝试来判断可用性的。

    nginx plus 有主动 health check,以及动态 upstream 的功能。前者也是有几次错误,后者完全平滑

    另外也有各家实现的动态 upstream,比如我写的基于 openresty + lua + etcd 的,微博开源的 C 模块的,以及好多
    salmon5
        13
    salmon5  
       2018-07-27 21:54:04 +08:00
    proxy_next_upstream 不幂等的请求有风险,幂等的完美。
    你需要服务发现、服务注册微服务架构,从架构上来解决这个问题。
    Kylinsun
        14
    Kylinsun  
       2018-07-27 21:56:39 +08:00 via Android
    kill -15
    ChristopherWu
        15
    ChristopherWu  
       2018-07-27 22:31:00 +08:00
    @swulling 感觉挺奇怪的。。
    @salmon5 正解

    》你需要服务发现、服务注册微服务架构,从架构上来解决这个问题。
    然而轮子太大了,造起来有点多。
    zookeeper 可以试试。
    MiffyLiye
        16
    MiffyLiye  
       2018-07-27 22:43:28 +08:00
    kubernetes 了解一下

    rolling update 部署时
    新服务启动并加入 load balance
    向旧服务发出关闭信号,开始倒计时
    load balancer 停止向旧服务转发新 connection
    旧服务关闭 inactive connections,处理 active connections,结束后自动退出,或
    倒计时结束,强行关闭旧服务

    liveness probe + restart 功能也是有的,过程与上面类似
    beginor
        17
    beginor  
       2018-07-27 22:58:30 +08:00 via Android
    这不是 zoo keeper 么的功能么?
    airyland
        18
    airyland  
       2018-07-27 23:06:49 +08:00
    在两个端口起服务,用脚本编辑 nginx 配置 upstream 卸载端口 1,reload,再编辑 nginx 将端口放加 reload,继续处理第 2 个端口。我的 Node 服务基本都是这样的部署方式,这样就完全是平滑部署了。
    0cean
        19
    0cean  
       2018-07-27 23:08:14 +08:00 via Android
    不差钱就上 f5 吧
    mgcnrx11
        20
    mgcnrx11  
       2018-07-28 13:54:14 +08:00
    主动通知的 nginx 的方式,譬如修改配置后 reload。

    其他的如 max fails, healthy check 都会在切换瞬间有几率发生错误的
    sagaxu
        21
    sagaxu  
       2018-07-28 18:25:04 +08:00 via Android
    计划性重启容易,重启前把主机从 upstream 里摘除,用 reload 是 client 感知不到的。重启后,再把它加入集群。

    比较不好处理的是服务突然崩溃,这种情况,有两个选择,一是把错误反馈给 client,然后累计错误 xx 次的时候从集群摘除。另一个选择是自动 try next upstream,client 不能感知到,但是并非所有业务都能无状态。

    累计 xx 次出错就自动摘除,也容易有坑,阈值设置的高了,要失败太多次才介入。设置的低了,容易产生血崩,尤其是某些 bug 导致服务出错,一不留神你群里机器就全被下架完了。

    所以需要配合主动的健康检测,做好平衡和折衷选择。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3587 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 10:53 · PVG 18:53 · LAX 02:53 · JFK 05:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.