例如一个服务两个实例,前面 nginx 负载均衡。
nginx 可以做到实时的健康监测吗?一旦一个服务 kill 不往这个服务上转发请求,不过这样好像还是有一个问题,我要升级必然要 kill 掉一个服务,kill 瞬间如果还有请求在这个实例里,那么这个请求就无法返回数据,这样用户感知到异常了。 所以最好的方式是要重启一个服务前,告诉负载均衡器不要转发请求到我这里,然后等一段时间等这个机器上所有请求都处理完,这个时候老的请求完毕,新的请求不过来,就可以更新重启。
nginx 下有这样的功能吗? haproxy 下倒是有 agent check 可以实现这个功能。
1
feverzsj 2018-07-27 19:56:35 +08:00
draining 功能只在收费版中有
|
2
veelog 2018-07-27 19:59:41 +08:00 via iPhone
nginx 有个 next_stream 就是这个用吧
|
3
swulling 2018-07-27 20:09:06 +08:00
一般都在服务这里做 graceful shutdown
如果服务这里不太好做,那么其实有一个比较简单的方法,就是每一个服务实例前面再套一个 nginx,每次 shutdown 的时候,先 graceful shutdown 这个 nginx,然后再杀服务。 我司有些产品线就是这么做的,把每个服务实例都绑一个 nginx,好处除了这个外,还自动就有了标准的监控、日志等等,较大的降低了服务改造成本。 |
4
ChristopherWu 2018-07-27 20:11:22 +08:00
@veelog 没有查到任何关于 next_stream 的资料
|
5
veelog 2018-07-27 20:23:25 +08:00 via iPhone
理解错了楼主的意思,next_stream 是描述当一个服务出现该配置描述的异常后,自动切到下一个服务,这个还不满足楼主的要求
|
6
veelog 2018-07-27 20:25:36 +08:00 via iPhone
楼主要求的功能,我可以试试后端服务不要直接 kill 掉,而是发一个信号,后端服务关闭监听的端口,这样新的连接不会过来了
|
7
misaka19000 2018-07-27 20:29:55 +08:00 via Android
当一台负载要下线了,先通知 nginx 此台负载下线,nginx 不再向此台负载转发请求,之后此台负载把当前进程的任务全部做完后在停止进程。上线的时候就很简单了,先上线再通知 nginx 就可以了
|
8
veelog 2018-07-27 20:30:25 +08:00 via iPhone
@ChristopherWu next_upstream
|
9
greatbody 2018-07-27 21:03:18 +08:00
如果是 java 等语言的话,可以考虑 controller 都继承一个鸡肋,这个鸡肋负责监听关闭信号,收到关闭信号后,就不再继续接收请求,只完成现有的请求。然后所有的已开始请求都处理完成后,自动退出。
这个是理论上的想法。 |
10
fengdianxun 2018-07-27 21:11:06 +08:00 via Android
熔断器?
|
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 模块的,以及好多 |
13
salmon5 2018-07-27 21:54:04 +08:00
proxy_next_upstream 不幂等的请求有风险,幂等的完美。
你需要服务发现、服务注册微服务架构,从架构上来解决这个问题。 |
14
Kylinsun 2018-07-27 21:56:39 +08:00 via Android
kill -15
|
15
ChristopherWu 2018-07-27 22:31:00 +08:00
|
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 功能也是有的,过程与上面类似 |
17
beginor 2018-07-27 22:58:30 +08:00 via Android
这不是 zoo keeper 么的功能么?
|
18
airyland 2018-07-27 23:06:49 +08:00
在两个端口起服务,用脚本编辑 nginx 配置 upstream 卸载端口 1,reload,再编辑 nginx 将端口放加 reload,继续处理第 2 个端口。我的 Node 服务基本都是这样的部署方式,这样就完全是平滑部署了。
|
19
0cean 2018-07-27 23:08:14 +08:00 via Android
不差钱就上 f5 吧
|
20
mgcnrx11 2018-07-28 13:54:14 +08:00
主动通知的 nginx 的方式,譬如修改配置后 reload。
其他的如 max fails, healthy check 都会在切换瞬间有几率发生错误的 |
21
sagaxu 2018-07-28 18:25:04 +08:00 via Android
计划性重启容易,重启前把主机从 upstream 里摘除,用 reload 是 client 感知不到的。重启后,再把它加入集群。
比较不好处理的是服务突然崩溃,这种情况,有两个选择,一是把错误反馈给 client,然后累计错误 xx 次的时候从集群摘除。另一个选择是自动 try next upstream,client 不能感知到,但是并非所有业务都能无状态。 累计 xx 次出错就自动摘除,也容易有坑,阈值设置的高了,要失败太多次才介入。设置的低了,容易产生血崩,尤其是某些 bug 导致服务出错,一不留神你群里机器就全被下架完了。 所以需要配合主动的健康检测,做好平衡和折衷选择。 |