即使主机健康且能够处理请求,ELB 也会返回 HTTP 504 错误

Posted

技术标签:

【中文标题】即使主机健康且能够处理请求,ELB 也会返回 HTTP 504 错误【英文标题】:HTTP 504 errors returned by ELB even when hosts are healthy and able to serve request 【发布时间】:2016-09-13 19:22:15 【问题描述】:

我有一项部署在 Amazon Web Services (AWS) 上的服务,特别是在弹性负载均衡器 (ELB) 后面的 2 个实例。可用区被选为所有三个 us-west-2a,b,c 但上述 3 个区域中只有 2 个在其中运行实例。

问题是即使流量/负载不是太高,但我仍然经常收到来自 ELB 的 HTTP 504 错误。

日志行如下所示

-1 -1 -1 504 0 0 0

依次为 --request_processing_time --backend_processing_time --response_processing_time --elb_status_code --backend_status_code --received_bytes --sent_bytes。 Description of what each field and response means can be found here

ELB 空闲超时为 60 秒。 KeepAlive 在后端实例上为“开启”。来自 ELB 的请求延迟正在检查中。我尝试增加KeepAliveTimeout,但无济于事。

有人知道如何进行吗?我什至不知道这个问题的根本原因。

PS:更像是第二个问题,有一些情况(当后端甚至不接受请求时,ELB 返回的 504 远少于 504),其中甚至后端返回 504,然后 ELB 将其转发给客户端.据我所知,HTTP 504 应该仅在后端超时时由代理返回。服务器本身如何返回 504?

【问题讨论】:

您能分享 ELB 上可用的 cloudwatch 指标吗?您还可以分享一下您有哪些类型的 ELB 健康检查以及 ELB 上有多少个可用实例? 您的例如 Apache 实例中是否配置了MaxRequestsPerChild?如果 ELB 与后端实例的持久连接在 ELB 使用该连接处理来自前端客户端的请求时终止,这也可能导致客户端看到 HTTP 504。 @Shibashis 2 个实例已附加到 ELB,如问题中所述。启用详细监控,包括 Backend_5xx、ELB_5xx、延迟、HealthyHosts、RequestCount 等。 Healthcheck 是一个简单的 HTTP 调用,超时时间为 5 秒,频率为 10 秒。 @Castaglia 我正在使用 apache 2.4,默认配置为 keep-alive 相关内容,MaxKeepAliveRequests 100,KeepAliveTimeout 为 5 秒。 健康主机数是否下降?还是保持在 2 不变。 【参考方案1】:

为了将来可能对其他人有所帮助,我在此发布我的发现:

1) 这个 504 0 HTTP 错误主要是因为 logrotate 重新加载 apache 而不是正常重启。 当前的 AWS 配置执行以下操作

/sbin/service httpd reload > /dev/null 2>/dev/null || true

所以将服务命令替换为apachectl -k graceful/sbin/service httpd graceful

我的 ec2 实例上的文件位置:/etc/logrotate.elasticbeanstalk.hourly/logrotate.elasticbeanstalk.httpd.conf

2) 因为 AWS 中默认的 logrotate 频率太高(每小时一次),至少对于我的用例而言,而这反过来又是每小时重新加载 apache,所以我也减少了它。

【讨论】:

那么您是如何将默认 Beanstalk 配置更改为使用 apachectl -k graceful @MaartenSander 在 ebextensions 中使用 elasticbeanstalk container_commands,类似于 command: sed -i 's/reload/graceful/g' /etc/logrotate.d/logrotate.elasticbeanstalk.httpd.conf。每次部署都会发生这种情况,因此由于自动缩放而进入的每台机器都具有相同的属性。此外,如果您升级 EBS 环境,则文件路径可能会从 /etc/logrotate.d/logrotate.elasticbeanstalk.httpd.conf 更改,因此每次升级 EBS 版本时都必须小心。【参考方案2】:

当后端连接超时时,ELB 会在其访问日志中的 backend_processing_time 列设置 -1。想想正在发生的事情,您的某些请求需要超过 60 秒才能让您的后端处理。要确认这一点,您可以检查您的延迟指标吗?查看此指标时请切换到最大值。如果您看到延迟经常达到 60 秒,它将证实我的猜测。

确认后,您可能需要增加 ELB 和后端的空闲超时时间。

【讨论】:

如问题中所述,请求的延迟受到检查。在最近的事件中,我看到 ELB 的最大延迟仅为 3 秒。

以上是关于即使主机健康且能够处理请求,ELB 也会返回 HTTP 504 错误的主要内容,如果未能解决你的问题,请参考以下文章

即使主机名不存在,可达性也会返回主机可达

ELB 总是将实例报告为 inservice

Spring CSRF:即使在设置请求标头后,Ajax 也会出现 403 错误

如何在 ELB 或 httpd 级别阻止不需要的请求

ELB 健康检查行为 - 健康阈值

即使请求了 format=json,YQL 也会返回 application/javascript