将rails应用程序部署到Heroku时,自动清除Memcached的最佳方法是什么?
我正在缓存主页,当我进行更改并重新部署时,页面将从缓存中提供,并且不会包含更新。
我想让它完全自动化。我不希望每次部署时都必须清除heroku控制台中的缓存。
谢谢!
答案 0 :(得分:32)
我使用bash脚本部署我的应用程序,该脚本自动化GitHub& Heroku推送,数据库迁移,应用程序维护模式激活和缓存清除操作。
在此脚本中,清除缓存的命令为:
heroku run --app YOUR_APP_NAME rails runner -e production Rails.cache.clear
这适用于Celadon Cedar和Heroku Toolbelt包。我知道这不是基于Rake的解决方案,但它非常有效。
注意:请确保将environment
命令的-e
/ runner
选项设置为production
,因为它将在development
上执行
编辑:几天后我在Heroku上遇到过这个命令的问题(Rails 3.2.21)。我没有时间检查问题的根源,但删除-e production
做了伎俩,所以如果命令不成功,请运行此命令:
heroku run --app YOUR_APP_NAME rails runner Rails.cache.clear
答案 1 :(得分:23)
[在Celadon Cedar Stack上]
- [2012年6月18日更新 - 这不再有效,将会看到我是否可以找到另一种解决方法]
我发现处理这些部署后挂钩的最简洁方法是锁定资产:在slug编译期间已经调用的预编译任务。点头对asset_sync Gem提出了这个想法:
Rake::Task["assets:precompile"].enhance do
# How to invoke a task that exists elsewhere
# Rake::Task["assets:environment"].invoke if Rake::Task.task_defined?("assets:environment")
# Clear cache on deploy
print "Clearing the rails memcached cache\n"
Rails.cache.clear
end
我只是将它放在lib / tasks / heroku_deploy.rake文件中,它很好地被拾取。
答案 2 :(得分:8)
我最终做的是创建一个新的rake任务,该任务部署到heroku然后清除缓存。我创建了一个deploy.rake文件,就是这样:
namespace :deploy do
task :production do
puts "deploying to production"
system "git push heroku"
puts "clearing cache"
system "heroku console Rails.cache.clear"
puts "done"
end
end
现在,我只需输入rake deploy:production。
,而不是输入git push heroku答案 3 :(得分:7)
2013年1月25日:这适用于在Cedar上的Ruby 1.9.3上运行的Rails 3.2.11应用程序
在Gemfile
添加以下行以强制使用ruby 1.9.3:
ruby '1.9.3'
使用以下内容创建名为lib/tasks/clear_cache.rake
的文件:
if Rake::Task.task_defined?("assets:precompile:nondigest")
Rake::Task["assets:precompile:nondigest"].enhance do
Rails.cache.clear
end
else
Rake::Task["assets:precompile"].enhance do
# rails 3.1.1 will clear out Rails.application.config if the env vars
# RAILS_GROUP and RAILS_ENV are not defined. We need to reload the
# assets environment in this case.
# Rake::Task["assets:environment"].invoke if Rake::Task.task_defined?("assets:environment")
Rails.cache.clear
end
end
最后,我还建议您在应用上运行heroku labs:enable user-env-compile
,以便在预编译过程中可以使用其环境。
答案 4 :(得分:2)
除了您在“应用程序启动”上运行的应用程序内部可以执行的操作之外,您可以使用会命中URL的heroku部署挂钩(http://devcenter.heroku.com/articles/deploy-hooks#http_post_hook)在您的应用程序中清除缓存
答案 5 :(得分:0)
我已添加config/initializers/expire_cache.rb
ActionController::Base.expire_page '/'
工作甜蜜!
答案 6 :(得分:0)
由于不推荐使用heroku gem,所以更新版本的Solomons非常优雅的答案是在lib/tasks/heroku_deploy.rake
中保存以下代码:
namespace :deploy do
task :production do
puts "deploying to production"
system "git push heroku"
puts "clearing cache"
system "heroku run rake cache:clear"
puts "done"
end
end
namespace :cache do
desc "Clears Rails cache"
task :clear => :environment do
Rails.cache.clear
end
end
然后在命令行中键入git push heroku master
而不是rake deploy:production
。
要清除缓存,您可以运行rake cache:clear
答案 7 :(得分:0)
我喜欢使用的解决方案如下:
首先,我实现了一个deploy_hook操作,该操作查找为每个应用程序设置不同的参数。通常我只是在“home”或“public”控制器上执行此操作,因为它不需要那么多代码。
### routes.rb ###
post 'deploy_hook' => 'home#deploy'
### home_controller.rb ###
def deploy_hook
Rails.cache.clear if params[:secret] == "a3ad3d3"
end
而且,我只是告诉heroku设置一个部署挂钩,以便在我部署时发布到该操作!
heroku addons:add deployhooks:http \
--url=http://example.com/deploy_hook?secret=a3ad3d3
现在,每次部署时,heroku都会回复一个HTTP帖子,让我知道部署工作正常。
对我来说就像一个魅力。当然,秘密令牌不是“高安全性”,如果有一个好的攻击向量,如果缓存清除了你的网站,那么就不应该使用它。但是,老实说,如果该网站对攻击至关重要,那么就不要在Heroku上托管它!但是,如果您想稍微增加安全性,那么您可以使用Heroku配置变量,而根本不在源代码中使用“令牌”。
希望人们觉得这很有用。
答案 8 :(得分:0)
我也遇到了这个问题,但是想要坚持使用git部署而不需要额外的脚本作为包装器。
所以我的方法是在slug生成期间使用标记当前预编译的uuid编写文件。这被称为assets:precompile
中的一个钩子。
# /lib/tasks/store_asset_cacheversion.rake
# add uuidtools to Gemfile
require "uuidtools"
def storeCacheVersion
cacheversion = UUIDTools::UUID.random_create
File.open(".cacheversion", "w") { |file| file.write(cacheversion) }
end
Rake::Task["assets:precompile"].enhance do
puts "Storing git hash in file for cache invalidation (assets:precompile)\n"
storeCacheVersion
end
Rake::Task["assets:precompile:nondigest"].enhance do
puts "Storing git hash in file for cache invalidation (assets:precompile:nondigest)\n"
storeCacheVersion
end
另一个是初始化程序,它根据缓存版本检查此id。如果它们不同,则会有另一个预编译,并且缓存将失效。
因此,应用程序旋转或关闭的频率或者工作者将分配多少节点无关紧要,因为slug生成只发生一次。
# /config/initializers/00_asset_cache_check.rb
currenthash = File.read ".cacheversion"
cachehash = Rails.cache.read "cacheversion"
puts "Checking cache version: #{cachehash} against slug version: #{currenthash}\n"
if currenthash != cachehash
puts "flushing cache\n"
Rails.cache.clear
Rails.cache.write "cacheversion", currenthash
else
puts "cache ok\n"
end
我需要使用随机ID,因为据我所知,无法获取git哈希或任何其他有用的ID。也许是ENV[REQUEST_ID]
,但这也是一个随机ID。
关于uuid的好处是,它现在也独立于heroku。