AWS Beanstalk - Passenger Standalone 在 Rails 4.2.1 迁移后不提供网页服务
AWS Beanstalk - Passenger Standalone not serving web pages after Rails 4.2.1 migration
我的 Rails 3.2.21 应用程序在 AWS Beanstalk 上 运行 在 Passenger Standalone 4.0.53 下正常运行。我将应用程序迁移到 Rails 4.2.1,并在我的本地开发机器 (Ubuntu, WEBrick) 上通过了所有测试。我将它部署到 Beanstalk (aws.push
),部署成功(从 /ondeck 复制到 /current)并且:没有。我浏览该站点并看到一个空白页面。没有 404 错误,什么都没有。
在旧版本上,我在本地有 pre-compiled 资产。这次,我让魔豆运行'bundle exec rake assets:precompile' webapp
。我在 eb-activity.log 中看到这成功了,我在 var/app/current/public/assets 中看到了这些资产。但这并不是不提供 public 资产,而是不提供 任何东西。
所以是的,有一个 /public 目录,这是 Passenger 所要求的。还有一个 /tmp 目录。这是 Rails 创建的 config.ru:
require ::File.expand_path('../config/environment', __FILE__)
run Rails.application
同样在 eb-activity.log 中,我看到这条消息似乎表明 Passenger 正在工作:
+ 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
时,它只是转到下一行——没有返回 headers 或其他网页内容。
我可以 运行 rails c
在 AWS 机器上启动 Rails 控制台。工作正常,可以访问数据库。
我在我的开发机器上 re-run 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 是空的,即使在我尝试访问该站点之后也是如此。
我刚刚尝试将日志级别设置为 DEBUG。 Passenger 重新启动后,它在 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 日更新
已在开发机器上尝试 pre-compiling 资产,然后进行部署。没有帮助。
2015 年 6 月 19 日更新
我现在有一个 Rails 4.2.1 测试应用程序成功 运行ning 在相同的 Beanstalk 环境下(64 位亚马逊 Linux 2014.09 v1.1.0 运行ning Ruby 2.0 - 乘客独立)。我看到在测试应用程序上,有四个 Passenger 进程:
- PassengerHelper(运行宁作为网络应用程序)
- PassengerLogging(运行宁作为网络应用程序)
- PassengerWatchdog(运行以 root 用户身份)
- PassengerHelper(运行宁作为根)
service passenger status
返回的pid对应root的PassengerHelper运行ning
在失败的实时应用程序中,只有一个 Passenger 进程:
- PassengerHelper(运行宁作为网络应用程序)
service passenger status
返回的 pid 不对应于活动进程。
很明显,四个 Passenger 进程中的三个在启动后崩溃了。到目前为止我还没有找到任何相应的错误日志,所以我不知道它们为什么会崩溃。
我终于想出了如何提高 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, is supposed to allow the health check (which only works on http) to bypass the force_ssl
> However, the exclude
option has been removed from Rail 4.2 per this commit。没有排除,健康检查失败,负载均衡器不会为应用程序提供服务。
默认的 Elastic Beanstalk 行为,如果你没有指定健康检查 URL,是简单地在端口 22 上 ping 服务器。但是我更喜欢健康检查实际上确认 Web 服务器是通过加载网页来工作。
我已经实施了这个解决方法:
从 production.rb 中删除 config.force_ssl
和 config.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 不匹配。但至少网络服务器再次为我的网站提供服务。
我的 Rails 3.2.21 应用程序在 AWS Beanstalk 上 运行 在 Passenger Standalone 4.0.53 下正常运行。我将应用程序迁移到 Rails 4.2.1,并在我的本地开发机器 (Ubuntu, WEBrick) 上通过了所有测试。我将它部署到 Beanstalk (aws.push
),部署成功(从 /ondeck 复制到 /current)并且:没有。我浏览该站点并看到一个空白页面。没有 404 错误,什么都没有。
在旧版本上,我在本地有 pre-compiled 资产。这次,我让魔豆运行'bundle exec rake assets:precompile' webapp
。我在 eb-activity.log 中看到这成功了,我在 var/app/current/public/assets 中看到了这些资产。但这并不是不提供 public 资产,而是不提供 任何东西。
所以是的,有一个 /public 目录,这是 Passenger 所要求的。还有一个 /tmp 目录。这是 Rails 创建的 config.ru:
require ::File.expand_path('../config/environment', __FILE__)
run Rails.application
同样在 eb-activity.log 中,我看到这条消息似乎表明 Passenger 正在工作:
+ 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
时,它只是转到下一行——没有返回 headers 或其他网页内容。
我可以 运行 rails c
在 AWS 机器上启动 Rails 控制台。工作正常,可以访问数据库。
我在我的开发机器上 re-run 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 是空的,即使在我尝试访问该站点之后也是如此。
我刚刚尝试将日志级别设置为 DEBUG。 Passenger 重新启动后,它在 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 日更新
已在开发机器上尝试 pre-compiling 资产,然后进行部署。没有帮助。
2015 年 6 月 19 日更新
我现在有一个 Rails 4.2.1 测试应用程序成功 运行ning 在相同的 Beanstalk 环境下(64 位亚马逊 Linux 2014.09 v1.1.0 运行ning Ruby 2.0 - 乘客独立)。我看到在测试应用程序上,有四个 Passenger 进程:
- PassengerHelper(运行宁作为网络应用程序)
- PassengerLogging(运行宁作为网络应用程序)
- PassengerWatchdog(运行以 root 用户身份)
- PassengerHelper(运行宁作为根)
service passenger status
返回的pid对应root的PassengerHelper运行ning
在失败的实时应用程序中,只有一个 Passenger 进程:
- PassengerHelper(运行宁作为网络应用程序)
service passenger status
返回的 pid 不对应于活动进程。
很明显,四个 Passenger 进程中的三个在启动后崩溃了。到目前为止我还没有找到任何相应的错误日志,所以我不知道它们为什么会崩溃。
我终于想出了如何提高 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, is supposed to allow the health check (which only works on http) to bypass the force_ssl
> However, the exclude
option has been removed from Rail 4.2 per this commit。没有排除,健康检查失败,负载均衡器不会为应用程序提供服务。
默认的 Elastic Beanstalk 行为,如果你没有指定健康检查 URL,是简单地在端口 22 上 ping 服务器。但是我更喜欢健康检查实际上确认 Web 服务器是通过加载网页来工作。
我已经实施了这个解决方法:
从 production.rb 中删除 config.force_ssl
和 config.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 不匹配。但至少网络服务器再次为我的网站提供服务。