前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >真正零停机 HAProxy 重载

真正零停机 HAProxy 重载

作者头像
小小科
发布2018-05-03 11:45:20
2.2K0
发布2018-05-03 11:45:20
举报
文章被收录于专栏:北京马哥教育北京马哥教育

Yelp 础设施团队的主要目标之一就是为了尽可能接近零停机时间。那也就是说当用户访问www.yelp.com作出动作的时候,网站的响应速度必须尽可能的快。一种方法是使用 HAProxy 负载均衡能够保持 www.yelp.com 网站的响应速度。通常我们在任何地方都使用 HAProxy 来保持网站的外部负载均衡、内部负载均衡,甚至运用到构建面向服务的架构中。我们发现在 Yelp 的每台机器上运行 HAProxy,均可作为 SmartStack 的一部分。 我们喜欢在发展 SOA 的时候使用 SmartStack 给我们带来的灵活性,但这种灵活性是有代价的。通常当服务或在服务后端执行增加或永久删除命令的的时候,整个基础设施不得不重新加载 HAProxy。这种重载方式会导致可靠性问题,因为 HAProxy 一旦运转起来就一直保持在工作状态且不会中断流量,但在重载的时候它会中断流量。 HAProxy 重载丢流量 HAProxy 的 1.5.11 版本不支持重启或重新加载配置时的零停机时间。相反,它支持快速重载——当一个新的 HAProxy 实例启动时,它尝试使用 SO_REUSEPORT 去绑定老 HAProxy 监听的相同端口并给老 HAProxy 实例发送信号去关闭。这种技术非常接近现代 Linux 内核的零停机时间,但这仍旧会经历一个短暂的时隙——当两个进程都绑定到端口时。在这个关键的时隙中,由于Linux内核自身(丢弃)处理多个接受进程的方式可能有流量会被丢掉。特别要提出来的,这个问题会潜在导致从 HAProxy 过来的新连接有一个 RST。这个问题是 SYN 包在老 HAProxy 被调用关闭前会被先放进其套接字队列中,这导致了这些连接的 RST。 这个问题有许多解决办法。例如,Willy Tarreau,HAProxy 的主要维护者,建议用户在重启 HAProxy 时丢掉 SYN 包,利用 TCP 的自动修复。不幸的是,RFC 6298 规定的初始 SYN 的超时时间是1s,Linux 内核坚守此规定。 因此,丢弃 SYN 意味着任何试图在 HAProxy 加载的 20-50ms 之间重建的连接将会遭受一个额外的秒级或更长的延迟。确切的时间依赖于客户端的 TCP 实现,而一些移动设备重试时间为 200ms,很多设备只在 3S 后重试。鉴于 HAProxy 重载的次数和和 Yelp 的流量,这成为了我们服务可靠性的一个障碍。 让HAProxy重载不丢包 为了避免延迟,我们采用了Willy提议的方案。他的方案实际上在不丢弃数据包上表现很好,但是额外的一秒延时是个问题。我们更好的解决方案是延迟SYN包直到重载已经完成,因为这样做只会对新的连接产生HAProxy重载所需要的延迟。 为了实现这种方案,我们求助于Linux队列原则(qdiscs)。Linux队列原则是用来管理Linux内核处理网络数据包的方式。具体地说就是你可以控制数据包是如何入队和出队,这提供了速率限制,优先或指定输出数据包的能力。有关更多qdiscs的详情, 我极力推荐lartc howto以及相关的man页面。 我们的一个SRE(网站可靠性工程师),Josh Snyder花了一些晚上的时间阅读了Linux内核源代码,发现了一个文档记录很少的工具:plug排队原则(qdisc),qdisc是从Linux 3.4以来就存在了。使用plug qdisc和以下标准Linux技术, 我们可以实现HAProxy重载零宕机:

  • tc:Linux流量控制。这使我们能够建立基于过滤器路由连接的排队规则。在最新的Linux版本上自带libnlutils,它提供了一些较新的qdiscs接口(如plug qdisc)。
  • iptables:用于包过滤和NAT(网络地址转换)的Linux工具。这个工具允许我们标识进入的SYN包。

SmartStack客户端连接到loopback接口向HAProxy请求,HAProxy幸好将进入的包变成为输出包。这意味着我们可以在loopback接口上建立如图1的队列原则。

Figure 1: Queueing Discipline 该设置的一个分类实现了使用 prio qdisc 队列规定的标准 pfifo_fast, 但只是使用了第四个“plug“通道。plug qdisc 并没有使他们退出队列,而是拥有队列数据包的性能。与一个 iptables 命令相结合的性能来允许我们在整个 HAProxy 重载期间重新定向,然后拔掉后重载的 SYN 插头的数据包。该控键(‘1:1’, ‘30:’等等)是允许我们一起连接 qdiscs,并且使用过滤器发送特定 qdiscs 的数据包。有关更多的信息,请查阅 lartc howto上面所引用的。 然后,我们把我们调用 qdisc_tool 的这个功能编进脚本。该工具允许我们的基础设施“保护”HAProxy 重载我们 plug 流量,重启haproxy,然后松开这个插头,交付延迟所有的 SYN 数据包。这个调用看起来像: qdisc_tool protect <normal HAProxy reload command> 由 GitHub 托管的 qdisc 命令 我们可以轻易地在诸如 Ubuntu Trusty 的 linux 发行版本上使用标准的用户空间实用工具来复制该技术。如果你的设置并没有 nl-qdisc-add,但有3.4+ Linux 内核,那么你可以通过 netlink 来手动地操纵该插头。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2015-04-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 马哥Linux运维 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档