alibaba / LVS

A distribution of Linux Virtual Server with some advanced features. It introduces a new packet forwarding method - FULLNAT other than NAT/Tunneling/DirectRouting, and defense mechanism against synflooding attack - SYNPROXY.
2k stars 682 forks source link

快速平滑的摘除 RS #34

Closed tanxi closed 3 years ago

tanxi commented 5 years ago

有方法能更快速下线 rs 吗?LVS 使用 DR 模式代理请求到后端 nginx,LVS 对 nginx 有配置 HTTP_GET 方式的健康检查,主动更新 nginx 的健康检查页使 LVS 的检查失败(返回非 200 状态码),这时 LVS 会摘除这台 rs,但是这时存在问题:

  1. 如果配置 inhibit_on_failure,新建联的请求不会再转发给这台 rs,但是以前已经建立的连接(可以通过 ipvsadm -Ln 查看 InActConn 的数量),还是会接收请求,导致摘除这个 rs 的过程非常久,1小时?
  2. 如果不配置 inhibit_on_failure,LVS 会直接把 rs 从 ipvs 的虚拟服务中删除,导致 client 发过来的包不再被转发给这台 rs,导致 client 端出现大量报错

上面 2 点在线上环境都是不能接受,还有什么办法能平滑快速的下线 RS 吗?

jlijian3 commented 5 years ago

@tanxi sysctl_ip_vs_expire_nodest_conn设为1,见ip_vs_core.c:1162 sysctl net.ipv4.vs.expire_nodest_conn = 1

tanxi commented 5 years ago

@tanxi sysctl_ip_vs_expire_nodest_conn设为1,见ip_vs_core.c:1162 sysctl net.ipv4.vs.expire_nodest_conn = 1

非常感谢!我测试一下这个配置。

tanxi commented 5 years ago

@tanxi sysctl_ip_vs_expire_nodest_conn设为1,见ip_vs_core.c:1162 sysctl net.ipv4.vs.expire_nodest_conn = 1

@jlijian3 你好,我验证了一下这个参数,rs 的 weight 被设置成 0 后,流量立刻被摘掉了,非常感谢!

不过现在又有一个新的不懂之处0-0. 我在网上查询了一下这个参数,然后发现了另外一个参数:expire_quiescent_template,参考的这份文档:https://www.kernel.org/doc/Documentation/networking/ipvs-sysctl.txt 我的理解是,expire_nodest_conn 是对直接从 ipvs 里删除 rs 时生效,expire_quiescent_template 是对把 rs weight 设置成 0 时生效,但是在测试的时候,把 expire_quiescent_template 参数设置成 1,并不能马上摘除流量,而 expire_nodest_conn 这个参数,对是否配置 inhibit_on_failure 参数,都能立马摘除流量。是我的理解错了吗?

jlijian3 commented 5 years ago

@tanxi expire_quiescent_template是针对配置了 persistence_timeout的vs weight=0,新建连接不会分配给这个rs,但旧的连接仍然能继续转发包,所以流量不能马上摘除 ipvs删除rs,会把rs状态置为UNAVALIBLE,不会直接删除,已经建立的连接直接丢弃包 expire_nodest_conn = 1 :就是如果rs状态是UNAVALIBLE,已经建立的连接收到包马上超时,从连接表删除,不管你weight是否为0

jlijian3 commented 5 years ago

@tanxi 流量没有马上摘除,估计是因为client和rs重传包 expire_nodest_conn使连接快速超时,重传包没有命中ipvs的连接,DR模式会继续走向协议栈上层,触发内核发送tcp reset。 如果是FULLNAT,NAT的话ipvs会自己发送reset

tanxi commented 5 years ago

@tanxi expire_quiescent_template是针对配置了 persistence_timeout的vs weight=0,新建连接不会分配给这个rs,但旧的连接仍然能继续转发包,所以流量不能马上摘除 ipvs删除rs,会把rs状态置为UNAVALIBLE,不会直接删除,已经建立的连接直接丢弃包 expire_nodest_conn = 1 :就是如果rs状态是UNAVALIBLE,已经建立的连接收到包马上超时,从连接表删除,不管你weight是否为0

@jlijian3 hi,设置 expire_nodest_conn = 1,当rs状态是UNAVALIBLE时,是LVS会立马返回 reset 给client吧?测试中有看见大量 Connection reset,这样在大流量情况下,还是会影响到服务,有更优雅的方式摘除 RS 吗?

tanxi commented 5 years ago

@tanxi expire_quiescent_template是针对配置了 persistence_timeout的vs weight=0,新建连接不会分配给这个rs,但旧的连接仍然能继续转发包,所以流量不能马上摘除 ipvs删除rs,会把rs状态置为UNAVALIBLE,不会直接删除,已经建立的连接直接丢弃包 expire_nodest_conn = 1 :就是如果rs状态是UNAVALIBLE,已经建立的连接收到包马上超时,从连接表删除,不管你weight是否为0

@jlijian3 hi,设置 expire_nodest_conn = 1,当rs状态是UNAVALIBLE时,是LVS会立马返回 reset 给client吧?测试中有看见大量 Connection reset,这样在大流量情况下,还是会影响到服务,有更优雅的方式摘除 RS 吗?

配置 inhibit_on_failure 后,请求不再有返回 Connection reset