丢掉 SYN 包,让 TCP 做余下的工作现在让我们尝试下丢掉 SYN 包的方法。这个方法可以以高的重启速率以达到重试连接的效果,为得到可靠的结果我每秒重启一次 HAProxy。 实验
1 2 3 4 5 6 7 8 | while [ 1 ]; do
sudo iptables -I INPUT -p tcp --dport 16000 --syn -j DROP
sleep 0.2
. /haproxy -f /tmp/haproxy .cfg -p /tmp/haproxy .pid -sf $( cat /tmp/haproxy .pid)
sudo iptables -D INPUT -p tcp --dport 16000 --syn -j DROP
sleep 1
done
|
iptables_experiment.sh 托管在 GitHub 结果
1 2 3 4 5 6 7 8 9 10 | $ ab -c 10 -n 200000 169.254.255.254:16000/
Benchmarking 169.254.255.254 (be patient)
...
Complete requests: 200000
Failed requests: 0
...
50% 2
95% 2
99% 6
100% 1002 (longest request)
|
iptables_result托管在GitHub 
图2: Iptables实验结果 正如预期的那样,我们没有丢弃请求但收到了一个额外的一秒钟的延迟。在请求绘制图图2中我们可以看到明显地看到命中重启时的两个峰值,其需要满满的一秒来完成请求。小于百分之一的测试请求观察到了高延迟,但这仍足以成为一个问题。
使用我们的平和重启方法在这个实验中,我们将使用 ‘-sf’ 选项重启HAProxy以使用我们的队列策略来延时传入的SYN包。为确保我们不是因为运气,我们做了一百万的请求。在本试验中我们对HAProxy重启了1500次以上。 实验
1 2 3 4 5 6 | while [ 1 ]; do
sudo nl -qdisc-add --dev=lo --parent=1:4 -- id =40: --update plug --buffer &> /dev/null
. /haproxy -f /tmp/haproxy .cfg -p /tmp/haproxy .pid -sf $( cat /tmp/haproxy .pid)
sudo nl -qdisc-add --dev=lo --parent=1:4 -- id =40: --update plug--release-indefinite &> /dev/nullsleep 0.100
done
|
tc_experiment.sh 托管在 GitHub 结果
1 2 3 4 5 6 7 8 9 10 | $ ab -c 10 -n 1000000 169.254.255.254:16000/
Benchmarking 169.254.255.254 (be patient)
...
Complete requests: 1000000
Failed requests: 0
...
50% 2
95% 2
99% 8
100% 29 (longest request)
|
tc_result 托管在 GitHub

图3: TC实验结果 成功啦!重启HAProxy已基本对我们的流量没有影响,在图3中可以看仅造成了轻微的延迟。请注意,该方法主要依赖HAProxy重载配置所花费的时间,由于我们使用了一个精简的配置,结果好的有点离谱。在我们的生产环境中,HAProxy重启时我们能观察到一个20ms的延迟影响。
结论这项技术似乎在我们实现目标——为开发构建提供坚实的基础服务设施上运行地很好。通过延迟SYN包进入每台机器上运行的HAProxy负载均衡器,我们能够最小化HAProxy重载所影响到的流量,这允许在达成我们SOA的情况下添加,删除和更改服务后端,而不必恐惧该过程显著影响用户的流量。
鸣谢感谢 Josh Snyder, John Billings 以及 Evan Krall 的优秀设计及对讨论的实现。 |