使用Tomcat从Elastic Load Balancer获取504错误

时间:2018-01-04 20:22:11

标签: amazon-web-services tomcat amazon-ec2 amazon-elb

我有一个应用程序在多个EC2实例上运行,并由Apache Tomcat提供服务。我在应用程序前面设置了一个AWS Elastic Load Balancer,一切都基本按预期工作。但是,我偶尔会从ELB获得一个随机504超时错误。这似乎与负载无关,因为我已经看到轻负载和重负载下的错误。此外,它似乎不会出现在任何常规模式或情况中。

在我的测试中,我得到了504个错误,因为我的应用程序响应的时间比ELB上的默认60秒超时要长。我通过将ELB超时提升到我的应用程序所需的级别来解决这个问题。但是,我现在得到的504错误很快就会发生。因此,例如,我看到的一个错误是响应时间大约为一秒的请求。当请求不可能在应用程序服务器上超时时,获得超时错误似乎很奇怪。

这可能与this question类似,但我无法从所提供的信息中得知。此外,我没有额外的负载均衡器,只有ELB直接到Tomcat。

2 个答案:

答案 0 :(得分:2)

所以,经过一番挖掘后,我发现了这个问题。 This page通过解释有关空闲和保持活动超时的一些细节来帮助解决这个谜团:

  

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

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

第一个场景是我看到并通过提高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的连接超时必须设置为低于两者   应用程序的空闲和保持活动超时以防止虚假504s   从生成。

在我开始使用ELB之前的某些时候,我设置了Tomcat超时,使其恰好高于默认的ELB超时。当我提高ELB超时时,我使其高于我在Tomcat中设置的connectionTimeout。将connectionTimeout提高到略高于我的新ELB超时,摆脱了神秘504错误。所以,我现在已经摆脱了“慢”和“快”超时错误。

Tomcat还有一个keepAliveTimeout设置,如果没有设置,默认设置与connectionTimeout相同。我没有设置它,因此修改connectionTimeout足以解决我的问题。

答案 1 :(得分:1)

ELB不太可能是问题的原因,而是显示您有问题。 504错误是Gateway Timeout,当服务器(在本例中为Tomcat)响应不够快时会发生错误。

(多年来我一直使用ELB进行极高负载服务,并且不同意其他SO答案链接的答案。虽然技术上是正确的,但非常高爆破率,如一秒钟内成千上万的请求,除非你的音量很高,我先看看你的应用程序。)

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

另请注意,ELB有一个运行状况检查设置,这些允许您设置某些规则来定义服务器是否正常运行 - 如果不是,ELB会将其从群集中删除,直到它再次运行正常。健康可以包括及时的反应。查看CloudWatch的ELB,看看最近是否有不健康的实例。

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