博客

容器扩展的艺术: 重试

Lori MacVittie 缩略图
洛里·麦克维蒂
2018 年 1 月 11 日发布

扩展容器不仅仅是在服务前面放置一个代理然后走开。 扩展不仅仅是分布,在快节奏的容器世界中,需要五种不同的功能来确保扩展:重试,断路器,发现分发和监控。

在这篇有关容器扩展艺术的文章中,我们将深入探讨重试。

重试

当你还是一个玩游戏的孩子时,重试的概念在很多游戏中都很常见。 失败后通常会大喊“重来!”,希望其他玩家让你再试一次。 有时他们会这么做。 有时却不是这样。 我注意到,这很少能阻止孩子尝试。 

当扩展应用程序(或您愿意的话,扩展服务)时,重试的概念大致相同。 代理在选择服务并尝试满足请求时收到错误。 在基本的负载均衡场景中,这通常通过检查 HTTP 响应代码来确定。 除了“200 OK”之外的任何内容都是错误。 其中包括网络和 TCP 层超时。 负载均衡器可以盲目地将失败的响应返回给 

疯狂引语

请求者,或者如果它足够智能,它可以重试该请求,希望后续请求能够得到成功的响应。

这听起来很基础,但在规模开始时,没有重试这样的事情。 如果失败了,那就失败了,我们会处理它。 通常通过手动尝试从浏览器重新加载。 最终,代理变得足够智能,可以自行执行重试,从而避免许多键盘的“CTRL”和“R”按钮磨损。

从表面上看,这是精神错乱定义的存在主义例子。 毕竟,如果请求第一次失败,我们为什么要期望它第二次(甚至第三次)会成功。

答案就在于失败的原因。 在扩展应用程序时,了解连接容量对故障的影响非常重要。 任何给定时间给定资源的负载不是固定的。 连接不断地被打开和关闭。 底层 Web 应用平台(无论是 Apache 还是 IIS、node.js 引擎还是其他堆栈)在容量方面都有明确的限制。 它只能维持 X 个并发连接。 当达到该限制时,打开新连接的尝试将会挂起或失败。

如果这是导致失败的原因,那么在代理接收失败响应的几微秒内,不同的连接可能已经关闭,从而为重试成功提供机会。

在某些情况下,故障是平台内部发生的。 可怕的“ 500 内部服务器错误”。 这种状态通常出现在服务器没有过载但调用了另一个(外部)服务但未能及时响应时。 有时这是数据库连接池达到极限的结果。 对外部服务的依赖可能会导致一系列错误,例如连接过载,这些错误通常会在您收到初始错误时得到解决。

您还可能会看到非常有用的“ 503 服务不可用”错误。 这可能是对过载的响应,但与所有 HTTP 错误代码一样,它们并不总能很好地预测出到底出了什么问题。 您可能会在 DNS 故障时或在 IIS 和 ASP 队列已满的情况下看到此情况。 可能性确实是多种多样的。 再说一次,当您收到错误时这些问题可能已经得到解决,因此重试肯定应该是您的第一反应。

当然,你不能一直重试直到天色渐暗。 就像 TCP 重传的意外后果(可能导致网络超载和接收方不堪重负)一样,重试最终变得徒劳无功。 对于在放弃之前应该重试多少次,并没有硬性规定,但通常重试 3 到 5 次。

此时,就该向请求者表示遗憾,并启动断路器了。 我们将在下一篇文章中深入探讨该功能。