这个问题困扰了我几个月……我承认自己是服务器管理的新手,我尝试在 EC2 上运行一个生产 Rails 应用程序。虽然我学到了很多东西,并且觉得用起来很舒服,但我不知道为什么在部署我的代码后,请求需要大约 1-2 分钟才能通过。从我通过谷歌收集到的所有信息来看,这是 Passenger 重新启动时出现的问题。解决方案似乎是编写一个滚动重启脚本。
我的服务器设置是:
- 亚马逊 EC2 Ubuntu 12.04 EBS 小型实例
- Nginx
- 乘客
- PostgreSQL 9.2
- Ruby 1.9.3
- Rails 3.2.11
- 使用 Capistrano 进行部署
这里的所有东西都非常基础……堆栈的任何部分几乎没有任何自定义配置。我首先使用 Rubber 部署到 Amazon,但随后从头开始构建服务器,因为我认为 Rubber 是部署后启动缓慢的原因……但它仍然挂起。当然,我可以进行滚动重启,添加另一个实例和负载平衡器以及第三个实例作为数据库实例,但目前这对这个项目来说没有意义。
我在其他主机上设置了一些几乎相同的服务器(centOS 上的 rails、nginx、passenger 和 postgresql),它们的部署速度要快得多。它们在 cap 部署完成和第一个请求通过之间的延迟几乎相同。
添加我的 cap 部署文件
require 'rvm/capistrano'
require 'bundler/capistrano'
require 'sidekiq/capistrano'
set :stages, %w(production staging)
set :default_stage, "staging"
require 'capistrano/ext/multistage'
set :application, "bundio"
set :repository, "[email protected]:my/project.git"
set :scm, "git"
set :shared_children, shared_children + %w{public/uploads} # include public/uploads in the shared folder to be symlinked across releases
ssh_options[:forward_agent] = true
ssh_options[:keys] = [File.join(ENV["HOME"], ".ec2", "my-keypair")]
set :deploy_to, "/var/www/apps/project"
set :rails_env, "production"
set :rvm_type, :system
set :rvm_path, "/usr/local/rvm"
set :keep_releases, 3
set :deploy_via, :remote_cache
desc "check production task"
task :check_production do
if stage.to_s == "production"
puts " \n Are you REALLY sure you want to deploy to production?"
puts " \n Enter the password to continue\n "
password = STDIN.gets[0..12] rescue nil
if password != 'doubleCheck'
puts "\n !!! WRONG PASSWORD !!!"
exit
end
end
end
#############
### Hooks ###
#############
before "deploy", "check_production"
# if you want to clean up old releases on each deploy uncomment this:
after "deploy:restart", "deploy:cleanup"
after "deploy:update_code", "deploy:symlink_shared"
after "deploy:update_code", "deploy:migrate"
after "deploy", "deploy:restart_daemons"
#################
### End hooks ###
#################
set :bundle_without, [:development,:test]
namespace :deploy do
namespace :assets do
task :precompile, :roles => :web, :except => { :no_release => true } do
begin
from = source.next_revision(current_revision)
rescue
err_no = true
end
if err_no || capture("cd #{latest_release} && #{source.local.log(from)} vendor/assets/ app/assets/ | wc -l").to_i > 0
run %Q{cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile}
else
logger.info "Skipping asset pre-compilation because there were no asset changes"
end
end
end
task :link_db do
#run "ln -s #{shared_path}/config/database.yml #{latest_release}/config/database.yml"
end
task :start do ; end
task :stop do ; end
task :restart, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
end
task :restart_daemons, :roles => :app do
sudo "monit restart all -g daemons"
end
desc "Symlink shared/* files"
task :symlink_shared, :roles => :app do
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
end
end
答案1
我在部署和第一个请求之间也遇到了同样的延迟。如果你的 RAM 很少,Passenger 可能需要几分钟才能启动。
Passenger 企业版保证您可以无停机时间进行部署:http://www.modrails.com/documentation/Users%20guide%20Nginx.html#PassengerRollingRestarts