我有一个应用程序在多个EC2实例上运行,并由Apache Tomcat提供服务。我在应用程序前面设置了一个AWS Elastic Load Balancer,一切都基本按预期工作。但是,我偶尔会从ELB获得一个随机504超时错误。这似乎与负载无关,因为我已经看到轻负载和重负载下的错误。此外,它似乎不会出现在任何常规模式或情况中。
在我的测试中,我得到了504个错误,因为我的应用程序响应的时间比ELB上的默认60秒超时要长。我通过将ELB超时提升到我的应用程序所需的级别来解决这个问题。但是,我现在得到的504错误很快就会发生。因此,例如,我看到的一个错误是响应时间大约为一秒的请求。当请求不可能在应用程序服务器上超时时,获得超时错误似乎很奇怪。
这可能与this question类似,但我无法从所提供的信息中得知。此外,我没有额外的负载均衡器,只有ELB直接到Tomcat。
答案 0 :(得分:2)
所以,经过一番挖掘后,我发现了这个问题。 This page通过解释有关空闲和保持活动超时的一些细节来帮助解决这个谜团:
从ELB接收504有两个直接原因:
- 应用程序实际上花费的时间比ELB的连接超时要长。这是一个缓慢的超时 - 504通常是 在几秒钟后返回,ELB的默认值为 60秒在这种情况下,有必要增加ELB 连接超时,或提高应用程序性能。
- 应用程序根本没有响应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的连接超时必须设置为低于两者 应用程序的空闲和保持活动超时以防止虚假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。