【问题标题】:Amazon ELB failing to serve the responseAmazon ELB 未能提供响应
【发布时间】:2012-06-17 23:04:38
【问题描述】:

我有一个在 Amazon Web Services 上运行的网站,它使用 Elastic Beanstalk 部署并在单个 EC2 微实例上运行。这是一个暂存环境,我是唯一可以访问它的人。使用 Apache JMeter,我模拟了六个用户在网站上导航,平均每 3 秒发出一次请求(图像、CSS、JS 和其他静态资源由 CloudFront 提供服务,不会在 EC2 实例上产生流量)。

问题是一段时间后(通常是从设置环境开始的 30-60 分钟),网站停止响应。我确信 Tomcat 仍在正常运行,因为我可以在日志 (catalina.out) 中看到 cronjobs 仍在执行。似乎只有 ELB 无法提供响应。

分析日志,Tomcat 上完全没有错误(/opt/tomcat7/logs/tail_catalina.log 或 /opt/tomcat7/logs/catalina.out 中没有)。一旦网站变得无法访问,以下错误就会开始出现在 /etc/httpd/logs/elasticbeanstalk-error_log 上:

[Thu Jun 14 20:26:42 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:26:42 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:26:50 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:26:50 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:27:20 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:27:20 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:27:43 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:27:43 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:27:50 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:27:50 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:28:20 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:28:20 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:28:42 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:28:42 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:28:50 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:28:50 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:29:20 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:29:20 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:29:42 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:29:42 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:29:50 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:29:50 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:30:20 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:30:20 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:30:43 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:30:43 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:30:50 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:30:50 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:31:20 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:31:20 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:31:43 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:31:43 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:31:50 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:31:50 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)
[Thu Jun 14 20:32:20 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:32:20 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)

...直到 EC2 实例最终终止(并自动启动一个新实例)。

如果我不提出任何请求(或者如果我提出的请求更少),则不会发生此问题。

非常感谢任何帮助。

谢谢!

【问题讨论】:

  • 与问题无关,但由于可搜索性:如果您尝试访问仅设置了 443 的 ELB 上的端口 80,您会看到“连接被拒绝”。

标签: tomcat amazon-web-services load-balancing amazon-elb


【解决方案1】:

让我从一个假设开始:

  • 您的 Tomcat 应用程序应该正在侦听 127.0.0.1:8999

如果是这样,日志事件:

[Thu Jun 14 20:26:42 2012] [error] (111)Connection refused: proxy: HTTP: attempt to   connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:26:42 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)

..建议应用程序侦听器死亡。您可以通过以下方式确认:

curl -v http://127.0.0.1:8999/

当站点正常运行时,curl 命令应该返回一个有效的 HTTP 响应,并且在您遇到中断时可能会返回一个 Connection refusedcouldn't connect to host。您还可以使用以下命令检查应用程序端口上的有效侦听器:

netstat -an | grep LISTEN | grep 8999

应用程序侦听器可能会死掉的原因有很多,包括但不限于:

  • JVM硬崩溃(使用ps查看JVM进程是否还在运行)
  • 应用程序软崩溃(查看 Tomcat 应用程序日志)
  • 文件描述符用完(使用 lsof | wc -l 并与应用程序用户的 ulimit -n 进行比较)

但是,大多数错误都会导致将错误消息写入 JVM 进程的stderr,通常会记录该消息。那是最好看的地方。如果一切都失败了,您可能需要尝试在前台运行您的 Tomcat 应用程序并启用调试日志记录。

【讨论】:

  • 非常感谢您的完整回答,@gabrtv。我只是在等待一个实例再次停止服务,我将使用您的建议来找出问题所在。你知道通常在 Amazon EC2 上登录的 stderr 在哪里吗?谢谢。
  • stderr 按进程记录。在这种情况下,您关心的是 Tomcat/JVM 进程的标准错误。通常它被写入一个日志文件,要么是 catalina.out,要么是一个单独的“错误”日志文件。您还应该搜索 /var/log/syslog/var/log/messages 以查找任何相关错误。
【解决方案2】:

我刚刚花了一天的时间来解决与此类似的问题。我有一个 WAR 文件部署到 Amazon Elastic Beanstalk 环境。与我不同的是,AEBS 环境启动的实例仅持续了 5 分钟,然后它就被终止并被 AEBS 的新实例替换。

经过相当多的挖掘(在我的实例还活着的情况下,在 5 分钟的块中)和一些 light reading 我发现 AEBS Tomcat 实例是使用 Apache 在端口 80 上接收请求创建的。/_hostmanager 上的请求是重新- 路由到端口 8999 和任何其他到端口 8080 (Tomcat)。部署到实例的名为“hostmanager”的 Ruby 应用程序在端口 8999 上进行侦听。该应用程序可能会向 AWS Elastic Beanstalk 主机管理器报告流量和其他统计信息,以允许 Elastic Beanstalk 环境获取环境负载的图片,并适当增加或减少实例的数量。

如果 AWS Elastic Beanstalk 主机管理器没有收到来自实例的主机管理器应用程序的响应,那么它将终止该实例并启动一个新实例。这可能就是您的网站持续 30 分钟然后死掉的原因。

所以我想这里的问题不在于您的 Java 应用程序在端口 8080 上提供服务,而是主机管理器应用程序没有在端口 8999 上侦听。这可能是导致的原因:

[Thu Jun 14 20:26:42 2012] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 127.0.0.1:8999 (localhost) failed
[Thu Jun 14 20:26:42 2012] [error] ap_proxy_connect_backend disabling worker for (localhost)

查看/opt/elasticbeanstalk/var/log/hostmanager.log,因为它可能会为您提供更多线索,了解正在发生的事情以及主机管理器应用程序不满意的原因。

在我的例子中,我的 hostmanager 应用程序正在运行一个 wget 到一个 Amazon S3 存储桶并且得到一个 404 响应(我通过查看上面提到的 hostmanager.log 发现了这一点)。这导致主机管理器无法启动。因此,当传入的请求被重新路由到端口 8999 时,没有任何东西在监听。失败。实例已终止。

与其试图找出 hostmanager 应用程序失败的确切原因,我决定将 Elastic Beanstalk 环境使用的 AMI 视为一个失败的原因。我最终放弃了它,并按照以下步骤获得了一个运行自定义 AMI 的新 Elastic Beanstalk 环境:

  1. 使用我的 WAR 文件创建新的 Elastic Beanstalk 环境
  2. 从它创建的实例创建了一个 AMI
  3. 从步骤 2 中创建的 AMI 创建了一个常规 EC2 实例
  4. 添加了一些我需要的额外位(例如 Tomcat 管理器)
  5. 从步骤 3 中创建的常规实例创建 AMI
  6. 将该 AMI 应用到 Elastic Beanstalk 环境

在不确切知道您的设置是什么的情况下,很难准确地提供帮助。虽然希望知道 hostmanager 侦听端口 8999、hostmanager.log 的位置和一些运气的组合会让你到达你想去的地方!

【讨论】:

    猜你喜欢
    • 2016-05-29
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    • 2017-07-04
    • 2012-07-28
    • 2016-03-21
    • 1970-01-01
    相关资源
    最近更新 更多