AWS Beanstalk - 在 Rails 4.2.1 迁移后,Passenger Standalone 不提供网页服务

Posted

技术标签:

【中文标题】AWS Beanstalk - 在 Rails 4.2.1 迁移后,Passenger Standalone 不提供网页服务【英文标题】:AWS Beanstalk - Passenger Standalone not serving web pages after Rails 4.2.1 migration 【发布时间】:2015-09-04 12:24:14 【问题描述】:

我的 Rails 3.2.21 应用程序在乘客独立 4.0.53 下的 AWS Beanstalk 上运行良好。我将应用程序迁移到 Rails 4.2.1 并让它通过了我本地开发机器(Ubuntu、WEBrick)上的所有测试。我将它部署到 Beanstalk (aws.push),部署成功(从 /ondeck 复制到 /current)并且:没有。我浏览到该站点并看到一个空白页面。没有 404 错误,什么都没有。

在旧版本上,我在本地预编译了资产。这一次,我让 Beanstalk 运行 'bundle exec rake assets:precompile' webapp。我在 eb-activity.log 中看到这成功了,我在 var/app/current/public/assets 中看到了这些资产。但这不是不服务于公共资产,而是不服务于任何东西

是的,Passenger 需要一个 /public 目录。还有一个 /tmp 目录。这是 Rails 创建的 config.ru

require ::File.expand_path('../config/environment', __FILE__)
run Rails.application

同样在 eb-activity.log 中,我看到这条消息似乎表明乘客正在工作:

+ service passenger restart
=============== Phusion Passenger Standalone web server started ===============
PID file: /var/app/support/pids/passenger.pid
Log file: /var/app/support/logs/passenger.log
Environment: production
Accessible via: http://0.0.0.0/

Serving in the background as a daemon.

但是当我从控制台运行curl -o - http://0.0.0.0 时,它只是转到下一行——没有返回任何标题或其他网页内容。

我可以运行 rails c 在 AWS 机器上启动 Rails 控制台。工作正常,可以访问数据库。

我已经在我的开发机器上重新运行eb init 以确保它正确连接,尽管git aws.push 一直在上传新版本。

我终止了 EC2 实例并让负载均衡器启动一个新实例。即构建成功。它第一次出现时(也是那时),我在 /var/app/support/logs/passenger.log 中看到了一些错误消息:

[ 2015-06-17 01:03:54.8281 2556/7fd8941b8740 agents/Watchdog/Main.cpp:538 ]: Options:  [redacted] 
[ 2015-06-17 01:03:55.2388 2559/7ff254abe740 agents/HelperAgent/Main.cpp:650 ]: PassengerHelperAgent online, listening at unix:/tmp/passenger.1.0.2555/generation-0/request
[ 2015-06-17 01:03:55.9207 2567/7fcb54570740 agents/LoggingAgent/Main.cpp:321 ]: PassengerLoggingAgent online, listening at unix:/tmp/passenger.1.0.2555/generation-0/logging
[ 2015-06-17 01:03:55.9209 2556/7fd8941b8740 agents/Watchdog/Main.cpp:728 ]: All Phusion Passenger agents started!
2015/06/17 01:03:57 [error] 2575#0: *3 "/var/app/current/public/index.html" is not found (2: No such file or directory), client: 127.0.0.1, server: _, request: "HEAD / HTTP/1.1", host: "0.0.0.0"
2015/06/17 01:04:02 [error] 2575#0: *4 "/var/app/current/public/app_check/index.html" is not found (2: No such file or directory), client: 172.31.21.97, server: _, request: "GET /app_check/ HTTP/1.1", host: "172.31.25.47"
[ 2015-06-17 01:06:10.4000 21317/7f433c999740 agents/Watchdog/Main.cpp:538 ]: Options:  [redacted] 
[ 2015-06-17 01:06:10.4047 21320/7f414cdd5740 agents/HelperAgent/Main.cpp:650 ]: PassengerHelperAgent online, listening at unix:/tmp/passenger.1.0.21316/generation-0/request
[ 2015-06-17 01:06:10.4090 21325/7f87c44f2740 agents/LoggingAgent/Main.cpp:321 ]: PassengerLoggingAgent online, listening at unix:/tmp/passenger.1.0.21316/generation-0/logging
[ 2015-06-17 01:06:10.4092 21317/7f433c999740 agents/Watchdog/Main.cpp:728 ]: All Phusion Passenger agents started!

通常,passenger.log 是空的,即使在我尝试访问该站点之后也是如此。

我刚刚尝试将日志级别设置为调试。乘客重新启动后,它会在 passenger.log 中打印:

[ 2015-06-18 17:52:28.3921 631/7f42fc9ce700 Pool2/SmartSpawner.h:298 ]: Preloader for /var/app/current started on PID 666, listening on unix:/tmp/passenger.1.0.627/generation-0/backends/preloader.p23dhh

为什么Passenger 不提供网页服务?我该如何解决这个问题?

2015 年 6 月 18 日更新

尝试在开发机器上预编译资产,然后进行部署。没有帮助。

2015 年 6 月 19 日更新

我现在有一个 Rails 4.2.1 测试应用程序在相同的 Beanstalk 环境下成功运行(64 位 Amazon Linux 2014.09 v1.1.0 运行 Ruby 2.0 -Passenger Standalone)。我看到在测试应用上,有四个Passenger进程:

PassengerHelper(作为 web 应用运行) PassengerLogging(作为 web 应用运行) PassengerWatchdog(以 root 身份运行) PassengerHelper(以 root 身份运行)

service passenger status 返回的 pid 对应于以 root 身份运行的 PassengerHelper。

在失败的实时应用上,只有一个乘客进程:

PassengerHelper(作为 web 应用运行)

service passenger status 返回的 pid 不对应活动进程。

显然,四个Passenger 进程中有三个在启动后崩溃。到目前为止我还没有找到任何对应的错误日志,所以不知道为什么会崩溃。

【问题讨论】:

你正在处理我讨厌的两件事。乘客和豆茎。只是一个建议您是否尝试过运行没有 Beanstalk 的 EC2 以及运行Passenger 所需的所有配置,然后加载您的应用程序看它是否响应?这将需要一些时间,但是您可能会发现可能缺少某个设置。也不要在此测试服务器中使用 ELB。只是一根骨头。祝你好运 我在 Beanstalk 的道路上走得太远了,无法轻易返回。我昨天确实设置了一个测试应用程序,该应用程序因 404 错误而主动失败。无法找出如何增加Passenger Standalone的日志级别——它仍然说它从0开始。也无法弄清楚它如何/从哪里确定从哪个Rails页面开始,尽管我认为这应该是自动。 解决了测试应用的 404 错误。出于某种原因,Passenger 不会使用默认的 Rails 模板回复 GET /。一旦我在 routes.rb 中添加了一个自定义主页和一个 root :to 它,测试应用程序就开始正确响应。我真正的应用程序已经有一个root :to,所以这不是问题。 这里是乘客作者。我认为您在错误的目录中启动了Passenger Standalone。看来您的应用程序位于 /var/app/current 中。但是service passenger start 输出似乎表明您在/var/app/support 中启动了Passenger Standalone。还是只是自定义了pid文件和​​日志文件的路径?您的 config.ru 到底在哪里? 在实时和测试应用程序中,Beanstalk 使用以下命令启动乘客服务:passenger start /var/app/current --nginx-version 1.6.2 -p 80 --pid-file /var/app/support/pids/passenger.pid -d -e production --user webapp --log-file /var/app/support/logs/passenger.log。同样在这两个应用程序中,config.ru 位于 /var/app/current。 【参考方案1】:

我终于想出了如何提高Passenger Standalone 的日志记录级别(博客here)。从日志中,我可以看到 Web 服务器正在使用 301 重定向响应 Beanstalk 健康检查。这意味着负载均衡器认为应用程序已死,因此将 503 错误发送回浏览器,浏览器显示一个空白页面。

301 重定向提示我使用 force_ssl 配置。我在production.rb中配置如下:

config.force_ssl = true
config.ssl_options =  exclude: proc  |env| env['PATH_INFO'].start_with?('/app_check')  

this post 之后的第二行应该允许运行状况检查(仅适用于 http)绕过 force_ssl> 但是,exclude 选项已从 Rail 4.2 中删除,每个 this commit .如果没有排除,运行状况检查将失败,负载均衡器将无法为应用提供服务。

默认的 Elastic Beanstalk 行为,如果您不指定运行状况检查 URL,则只是简单地在端口 22 上 ping 服务器。但是我更喜欢运行状况检查实际上通过加载网页来确认 Web 服务器正在工作.

我已经实现了这个解决方法:

从 production.rb 中删除 config.force_sslconfig.ssl_options

将以下内容添加到 application.rb,假设可以从 StaticPagesController#health_check 访问健康检查:

force_ssl if: :require_ssl? # see private method below for conditions

private

def require_ssl?
  Rails.env.production? && !(controller_name == "static_pages" && action_name == "health_check")
end

我可能仍然有一个Passenger 或Nginx 问题,因为我仍然只有一个Passenger 进程在运行,并且它的PID 与service passenger status 的PID 不匹配。但至少网络服务器再次为我的网站提供服务。

【讨论】:

以上是关于AWS Beanstalk - 在 Rails 4.2.1 迁移后,Passenger Standalone 不提供网页服务的主要内容,如果未能解决你的问题,请参考以下文章

AWS Elastic Beanstalk——rails 部署问题

Rails aws elastic beanstalk部署错误与数据库适配器

使用 AWS 弹性 beanstalk 负载均衡器在 Rails 上实施 https 连接

在 AWS Elastic Beanstalk 上部署 rails 应用程序

在 AWS 弹性 beanstalk 上部署 Rails - 静态资产路由不起作用

在 AWS Elastic Beanstalk / Rails 上配置 HTTPS