我们的应用程序托管在 EC2 上,但由于应用程序的性质,它需要极高的可用性。我们有一个在 Linode 上运行的应用程序映像作为故障转移。
但是,将 DNS 转换为 Linode 需要一些时间。我们想出了一个策略来尽量减少停机时间,但我希望得到一些关于如何最好地实施它的建议。
该应用程序是一个 ROR 应用程序。我们在 EC2 上运行 6 个前端节点,并使用 Nginx 作为带有 proxy_pass 的负载均衡器。
但是,Linode 上的负载均衡器并不平衡到 Linode 节点,而是平衡到 EC2 节点。这样,我们的 DNS 记录中就有了 Linode LB 的 IP。因此,当客户端连接时,DNS 会轮询到 EC2 或 Linode LB。然后,所选的 LB 会将请求重定向到 EC2 上的一个节点。如果 EC2 中断,我们只需更改 Linode LB 的配置以平衡到它自己的节点(加上其他东西,如数据库翻转等)。
我知道这对性能来说不太好,但可靠性对我们来说更重要。
问题是,无论出于何种原因,Linode LB 都无法连接到 EC2。在这种情况下,Nginx 将返回 502 Bad Gateway 错误,这不会导致客户端使用 DNS 故障转移。
我们希望有一种方法可以在这种情况发生时强制客户端使用 DNS 回退。有办法吗?最好使用 Nginx,但如果不支持,则会考虑其他解决方案。
谢谢!
答案1
我喜欢这种方法,这是我最喜欢的,如果你来旧金山,我会请你喝杯啤酒!
两个答案,首先针对你的 502 问题,你应该将其添加到你的 nginx,因此如果至少有一些有能力的节点,nginx 将重试(默认情况下,在 502 上它会放弃):
http://wiki.nginx.org/HttpProxyModule#proxy_next_upstream
proxy_next_upstream
syntax: proxy_next_upstream [error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off];
其次,对于“返回 DNS”,您需要稍微改变方法。对于这些设置,我通常会将 DNS 拉回到应用程序节点本身,以测试通过负载平衡器到终端节点的连通性。作为额外奖励,您可以将 DNS 与您的应用程序集成,并在应用程序死机时关闭 DNS 服务器。这里的想法是让客户端 DNS 请求“测试”整个路径是否正常工作,而不仅仅是与 LB 的连接。显然您不能为此使用 NGINX,我为此使用了 pf 规则,您可以在 iptables 中执行相同操作。您只需将请求轮询到后端节点并在后端服务器上运行绑定。然后,这个想法是确保您有多个 NS 条目,每个“LB”一个。客户端将负责测试每个 NS 记录,在我进行的测试中,平均故障转移时间为 2 秒,并且它适用于我们查看的 99% 的操作系统。让我知道这是否有意义。它将比客户端已经发出第一个 TCP 请求后尝试恢复的任何场景效果更好。
根据 Gomez 和 Keynote 的监控,使用此解决方案我建立的网站保持了 100% 的可用性。正如您之前提到的,它可能会导致 DNS 查找的一些初始性能损失,但网站始终可以正常工作,客户对此非常满意(我的寻呼机也是如此)。