代码之家  ›  专栏  ›  技术社区  ›  ittupelo

504来自使用Tomcat的弹性负载平衡器的错误

  •  9
  • ittupelo  · 技术社区  · 7 年前

    我有一个应用程序运行在多个EC2实例上,由Apache Tomcat提供服务。我在应用程序前面安装了一个AWS弹性负载平衡器,一切基本上都按预期工作。然而,我偶尔会从ELB得到一个随机的504超时错误。这似乎与负载无关,因为我已经看到了轻负载和重负载下的错误。而且,它似乎没有任何规律或情况发生。

    在测试的早期,我收到了504个错误,因为我的应用程序响应时间比ELB上默认的60秒超时时间长。我通过将ELB超时提高到我的应用程序所需的级别来解决这个问题。然而,我现在遇到的504个错误发生得很快。例如,我看到的一个错误是一个响应时间约为1秒的请求。当应用服务器上的请求不可能超时时,出现超时错误似乎很奇怪。

    这可能与 this question ,尽管我无法从所提供的信息中分辨出来。此外,我没有额外的负载平衡器,只需直接访问Tomcat即可。

    2 回复  |  直到 7 年前
        1
  •  5
  •   ittupelo    7 年前

    所以,在进一步挖掘之后,我发现了问题所在。 This page 通过解释空闲和保留超时的一些细节,有助于解开谜团:

    从ELB收到504有两个直接原因:

    1. 实际上,应用程序的响应时间比ELB的连接超时时间长。这是一个缓慢的超时–504通常是 秒数后返回,ELB的默认值为 60秒。在这种情况下,有必要增加ELB 连接超时,或提高应用程序性能。
    2. 应用程序根本没有响应ELB,而是在请求数据时关闭其连接。这是一个快速超时 504通常会在毫秒内返回,远低于 ELB的超时设置。

    第一个场景是我所看到的,并通过提高ELB超时来解决。第二个场景描述了我在提高ELB超时后看到的令人困惑的行为。我的日志文件具有“-1-1-1”模式,如本文中的示例日志:

    2015-12-11T13:42:07.736195Z my-elb 10.0.0.1:59893 - -1 -1 -1 504 0 0 0 "GET http://my-elb/ HTTP/1.1" "curl/7.19.7" - -
    

    从结论来看:

    简而言之,ELB的连接超时必须设置为低于 应用程序的空闲和保留超时可防止虚假504 不被生成。

    在开始使用ELB之前的开发过程中的某个时候,我设置了Tomcat超时,使其恰好高于默认的ELB超时。当我加快ELB超时时,我使其高于 connectionTimeout 我已经加入了Tomcat。提高 连接超时 略高于我的新ELB超时,消除了神秘的504错误。所以,我现在已经消除了“慢”和“快”超时错误。

    Tomcat还有一个 keepAliveTimeout 默认值与相同的设置 连接超时 如果未设置。我没有设置,所以修改 连接超时 足以解决我的问题。

        2
  •  0
  •   Tom Harrison Andy Royal    7 年前

    ELB不太可能是 原因 而是表明你有一个问题。504错误为 Gateway Timeout 当服务器(在本例中为Tomcat)响应速度不够快时会发生这种情况。

    (我多年来一直在使用ELBs提供极高负载的服务,不同意其他SO答案的链接答案。虽然这在技术上是正确的,但在 极其 高突发率,如每秒数千个请求,除非您的容量如此之大,否则我会首先查看您的应用程序。)

    要确认它不是ELB,最明显的测试是直接针对集群中的一个Tomcat服务器测试请求。如果无法路由到Tomcat实例,可以尝试 curl 从要测试的实例发送到localhost。

    还请注意,ELB有一个健康检查设置,允许您设置某些规则来定义服务器是否健康——如果不健康,ELB将从集群中删除它,直到它再次健康。健康可以包括及时响应。查看CloudWatch for the ELB,看看最近是否有不健康的实例。

    如果您在开发中看到504,现在它更频繁了,我想这实际上是一个负载或性能问题。最典型的情况是,由于底层应用程序的问题,Java遇到了一些垃圾收集问题。查看EC2实例的CloudWatch指标,看看内存或CPU是高还是高。