服务如何做到平滑升级?

2018-07-27 19:45:02 +08:00
 twogoods

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

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

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

6762 次点击
所在节点    程序员
21 条回复
feverzsj
2018-07-27 19:56:35 +08:00
draining 功能只在收费版中有
veelog
2018-07-27 19:59:41 +08:00
nginx 有个 next_stream 就是这个用吧
swulling
2018-07-27 20:09:06 +08:00
一般都在服务这里做 graceful shutdown

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

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

这个是理论上的想法。
fengdianxun
2018-07-27 21:11:06 +08:00
熔断器?
hash
2018-07-27 21:29:29 +08:00
@greatbody 输入法好评 /手动笑哭
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
2018-07-27 21:54:04 +08:00
proxy_next_upstream 不幂等的请求有风险,幂等的完美。
你需要服务发现、服务注册微服务架构,从架构上来解决这个问题。
Kylinsun
2018-07-27 21:56:39 +08:00
kill -15
ChristopherWu
2018-07-27 22:31:00 +08:00
@swulling 感觉挺奇怪的。。
@salmon5 正解

》你需要服务发现、服务注册微服务架构,从架构上来解决这个问题。
然而轮子太大了,造起来有点多。
zookeeper 可以试试。
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
2018-07-27 22:58:30 +08:00
这不是 zoo keeper 么的功能么?
airyland
2018-07-27 23:06:49 +08:00
在两个端口起服务,用脚本编辑 nginx 配置 upstream 卸载端口 1,reload,再编辑 nginx 将端口放加 reload,继续处理第 2 个端口。我的 Node 服务基本都是这样的部署方式,这样就完全是平滑部署了。
0cean
2018-07-27 23:08:14 +08:00
不差钱就上 f5 吧
mgcnrx11
2018-07-28 13:54:14 +08:00
主动通知的 nginx 的方式,譬如修改配置后 reload。

其他的如 max fails, healthy check 都会在切换瞬间有几率发生错误的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/474772

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX