- 浏览: 94808 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
clcai:
[/color][color=green]
div实现模态窗口(转) -
clcai:
[align=left][/align][size=small ...
div实现模态窗口(转) -
reyesyang:
很有帮助的文章。
[翻译]来自Rails Envy的Rails Cache教程 part1 -
JasonChi:
Hooopo 写道google group的ROR北京社区在哪 ...
rails 学习(转) -
Hooopo:
google group的ROR北京社区在哪里啊
rails 学习(转)
原文地址:http://railsenvy.com/2007/3/20/r ... ing-tutorial-part-2
Part1地址:http://www.ruby-lang.org.cn/forums/thread-3158-1-1.html
本教程的编写顺序是按照各个缓存的效率来排序的,Page缓存最快,所以在第一篇教程就介绍了,这篇教程就介绍其它的几种缓存。
Action 缓存
Action缓存和Page缓存十分相似,唯一的区别就是对页面的请求会触及Rails服务器并且filter还是会运行。类似下面代码这样设置Action缓存:
CODE:
class BlogController < ApplicationController
layout 'base'
before_filter :authenticate # <--- Check out my authentication
caches_action :list, :show
可以从代码中看到,用户必须通过认证才能访问list action,当对list进行请求时可以从 /log/development.log看到如下日志
CODE:
Processing BlogController#list (for 127.0.0.1 at 2007-03-04 12:51:24) [GET]
Parameters: {"action"=>"list", "controller"=>"blog"}
Checking Authentication
Post Load (0.000000) SELECT * FROM posts ORDER BY created_on LIMIT 10
Rendering blog/list
Cached fragment: localhost:3000/blog/list (0.00000)
Completed in 0.07800 (12 reqs/sec) | Rendering: 0.01600 (20%) | DB: 0.00000 (0%) | 200 OK [http://localhost/blog/list]
看到“Cached fragment: localhost:3000/blog/list”这行了吗?这表示有缓存文件生成,并且可以找到如下这个文件:
/tmp/cache/localhost:3000/blog/list.cache
默认的情况是, Action缓存会在/tmp/cache/目录下缓存文件,而不是像Page缓存那样直接输出.html文件,是输出.cache文件。如果你在单个应用中包含了一个以上的自域名,缓存文件的路径会包含主机和端口(localhost:3000)。这种情况下每个自域名会缓存在各自的目录下。
如果打开“list.cache”文件,就会看到其中的内容是完整的静态html页面,就像Page缓存的一样。那它们之间有什么区别呢?
如果我们再次对页面做出请求(经过上面的请求之后),来看看/log/development.log:
CODE:
Processing BlogController#list (for 127.0.0.1 at 2007-03-04 13:01:31) [GET]
Parameters: {"action"=>"list", "controller"=>"blog"}
Checking Authentication
Fragment read: localhost:3000/blog/list (0.00000)
Completed in 0.00010 (10000 reqs/sec) | DB: 0.00000 (0%) | 200 OK [http://localhost/blog/list]
如你所见, 前置过滤器Authentication执行了,接着读取了缓存文件,然后输出。所以在这个情况下,依然是输出那个完整的缓存文件,并且还做了用户认证的检查。
这里值得注意的是,action执行前前置过滤器必须被执行。另一方面,你也可能会缓存到一个错误的html文件。
怎样清理Action缓存
如教程Part1中,缓存必须在数据发生变化后被清除掉。这里也是用sweepers,只不过在/app/sweepers/blog_sweeper.rb中"expire_page" 要改为 "expire_action":
CODE:
# Expire the list page now that we posted a new blog entry
expire_action(:controller => 'blog', :action => 'list')
# Also expire the show page, incase we just edited a blog entry
expire_action(:controller => 'blog', :action => 'show', :id => record.id)
也可以用以下的rake任务来清除 Action 缓存和 Fragment 缓存:
CODE:
rake tmp:cache:clear
这个rake任务会删除所有的.cache文件。
Fragment Caching
使用了缓存之后会让应用变得飞快,但是由于这是动态的web应用,缓存整个页面并且总能命中这是不实际的,所以有了Fragment缓存。Fragment缓存能缓存页面中的一部分。
要对Blog应用中Post列表进行Fragment进行缓存就要编辑 /app/views/blog/list.rhtml:
CODE:
<strong>My Blog Posts</strong>
<% cache do %>
<ul>
<% for post in @posts %>
<li><%= link_to post.title, :controller => 'blog', :action => 'show', :id => post %></li>
<% end %>
</ul>
<% end %>
这段cache do的代码会创建文件/tmp/cache/localhost:3000/blog/list.cache,即使用当前的controller和action来进行命名。当下次请求来到并命中cache do部分的代码时就会读取刚刚说到那个缓存文件。让我们查看/log/development.log,来看看第一次和第二次请求中发生了什么:
CODE:
Processing BlogController#list (for 127.0.0.1 at 2007-03-17 22:02:16) [GET]
Authenticating User
Post Load (0.000230) SELECT * FROM posts
Rendering blog/list
Cached fragment: localhost:3000/blog/list (0.00267)
Completed in 0.02353 (42 reqs/sec) | Rendering: 0.01286 (54%) | DB: 0.00248 (10%) | 200 OK [http://localhost/blog/list]
Processing BlogController#list (for 127.0.0.1 at 2007-03-17 22:02:17) [GET]
Authenticating User
Post Load (0.000219) SELECT * FROM posts
Rendering blog/list
Fragment read: localhost:3000/blog/list (0.00024)
Completed in 0.01530 (65 reqs/sec) | Rendering: 0.00545 (35%) | DB: 0.00360 (23%) | 200 OK [http://localhost/blog/list]
有没有感觉到一些冗余?
在第一次请求时生成了缓存,第二次时读取缓存,但是对Posts的SQL查询进行了两次。我们已经对SQL查询的结果缓存到页面中了,我们在缓存之后不用再进行SQL查询了,是吗?
解决这个问题的其中的一个方法就是编辑/controllers/blog_controller.rb,在查询前加上一个条件检查:
CODE:
def list
unless read_fragment({})
@post = Post.find(:all, :order => 'created_on desc', :limit => 10) %>
end
end
现在只会在没有缓存的时候才有查询出现。或者有人会想,把这个请求放到view中的cache do代码块中不就好了吗?但是这个是MVC架构啊。
猜猜怎样清除Fragment缓存
CODE:
# Expire the blog list fragment
expire_fragment(:controller => 'blog', :action => 'list')
没错吧?
在分页中使用Fragment缓存
默认情况下,缓存的命名是通过直接查找当前的controller和action名字来决定的。也就是说controller 为 "blog"并且 action 为 "list"就会缓存到 "/localhost:3000/blog/list.cache"。
在分页的情况下,就要把分页的页码加到缓存文件中。
CODE:
blog_controller.rb
应该类似下面那样处理:
CODE:
def list
unless read_fragment({:page => params[:page] || 1}) # Add the page param to the cache naming
@post_pages, @posts = paginate :posts, :per_page => 10
end
end
在这里代码也可以为:read_fragment({:controller => 'blog', :action => 'list', :page => params[:page] || 1}),但Rails决定了前两个参数,这个无法改变,所以可以省略。
/views/blog/list.rhtml如下:
CODE:
<% cache ({:page => params[:page] || 1}) do %>
... All of the html to display the posts ...
<% end %>
这段代码会在第一次访问 /blog/list时,会创建 /localhost:3000/blog/list.page=1.cache 的缓存文件,按理可知访问分页2时会创建缓存文件/localhost:3000/blog/list.page=2.cache。 Pretty cool!
对Fragment缓存高级命名机制
大多数时候要对cache进行命名,这里有个示例:
话说现代的Web设计中每个页面都有一个用户自定义的导航目录(nav menu)。这里是一个列出用户要完成的项目任务(task)的导航目录:
CODE:
<div id="nav-bar">
<strong>Your Tasks</strong>
<ul>
<% for task in Task.find_by_member_id(session[:user_id]) %>
<li><%= task.name %></li>
<% end %>
</ul>
</div>
这个会在站点的每个页面中显示,如果能在用户第一次访问页面时缓存起来,在之后的访问就不用总是打扰数据库了。那就要对代码进行一点点改动:
CODE:
<div id="nav-bar">
<strong>Your Tasks</strong>
<% cache (:controller => "base", :action => "user_tasks", :user_id => session[:user_id]) do %>
<ul>
<% for task in Task.find_by_member_id(session[:user_id]) %>
<li><%= task.name %></li>
<% end %>
</ul>
<% end %>
</div>
当user_id为1时会创建缓存文件/localhost:3000/base/user_tasks.user_id=1.cache。
Fragment缓存命名示例
这里有些用户命名缓存的例子:
CODE:
cache ("turkey") => "/tmp/cache/turkey.cache"
cache (:controller => 'blog', :action => 'show', :id => 1) => "/tmp/cache/localhost:3000/blog/show/1.cache"
cache ("blog/recent_posts") => "/tmp/cache/blog/recent_posts.cache"
cache ("#{request.host_with_port}/blog/recent_posts") => "/tmp/cache/localhost:3000/blog/recent_posts.cache"
怎样一次sweep多个缓存
上面的分页的Fragment缓存最后生成了很多缓存文件,已知的清除方法只是:
CODE:
expire_fragment(:controller => 'blog', :action => 'list', :page => 1)
expire_fragment(:controller => 'blog', :action => 'list', :page => 2)
expire_fragment(:controller => 'blog', :action => 'list', :page => 3)
.....
但是这里还有一个方法来做这些事情:
CODE:
expire_fragment(%r{blog/list.*})
这样会查找blog/list下的所有cache文件。使用这个方法要明白下面几点:
不能在Memcached(下面会提到)下运行。
这种方法会对所有的cache文件进行正则匹配,如果你的系统中有4,000+个cache文件,这会让你的系统处理很久。
如果你不慎写错了正则表达式,那可能会出大问题。
Action/Fragment缓存的几种缓存机制
Page 缓存只能使用文件系统。Action 和 Fragment缓存就有几种选择:
File Store - (默认) - 把缓存放在磁盘中 (默认在 /tmp/cache/ 目录)。
Memory Store - Rails服务器的处理方法,放在内存。
DRb Store - 使用DRb服务器。
MemCache Store - MemCache是一个高性能的缓存处理程序。注意它不是用Ruby实现的。
作者认为FileStore是一开始最好的选择,在以后升级为其它的方式(如MemCache)也不难,要改变缓存文件存储的位置可以编辑config/environment.rb:
CODE:
ActionController::Base.fragment_cache_store = :file_store, "/path/to/cache/directory"
ActiveRecord查询缓存
这是第四种缓存机制,对这种机制并没有过多的文档,它只出现在 Rails Edge中,现在来介绍一下。
ActiveRecord并不需要做配置,在默认情况下会自动运行。看看这个action:
CODE:
class BlogController < ApplicationController
def some_complex_thing
post = Post.find(1)
# .... Do alot of other stuff
post_again = Post.find(1)
end
end
在没有AR缓存的情况下,SQL查询会进行两次。现在使用了AR缓存后,在第二次的查询会读取第一次查询时生成的缓存。这样就不用担心在单个的Action中两次相同的查询会查询数据库两次了。
不过这里的例子不够直观,但想像复杂的认证代码。很多时候可能会在多种认证方式中进行用户数据的查询,而且这是发布在几个不同地方的代码中的,如果缓存了结果,无疑对性能有提高。
查询缓存在action中第一次查询时缓存,在action结束时清除掉缓存。这里没有真正的存储,当 inserts/updates/deletes 执行时,全部缓存就会刷新。如果你要在多个actions或users间缓存数据,请使用MemCache。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/joliny/archive/2008/03/05/2152244.aspx
发表评论
-
Can't install RMagick 2.13.1. Can't find MagickWand.h.
2012-01-09 14:45 2216=== ln -s /usr/local/include/ ... -
rails 3.1 mysql2.gem 安装
2011-11-11 15:20 815http://www.cnblogs.com/ilazysof ... -
用imagemagick和tesseract-ocr破解简单验证码 自我补充记录
2011-10-13 16:28 1958http://hooopo.iteye.com/blog/99 ... -
mac虚拟机本地通过git上传项目到github时出现的诡异问题
2011-10-02 23:27 2017错误为: Permission denied (public ... -
mac rails3.1 启动mysql报错解决
2011-09-27 23:18 1245/Library/Ruby/Gems/1.8/gems/m ... -
windows rails+apache+ssl 配置
2011-09-08 19:51 1103apache 中ssl配置详见: http://apps.hi ... -
ruby on rails linux部署环境下定时任务解决小记
2011-08-31 18:09 1038原本系统在开发环境下的定时任务用的是 rufus-schedu ... -
rails rake 用法说明
2011-08-31 11:44 1466原文:Ruby on Rails Rake Tut ... -
郁闷的部署
2011-08-22 16:11 731今天想给跑在windows下的系统用apache+mongre ... -
浅析Ruby on Rails部署方案(转)
2011-08-22 14:37 910前言 两年过去了,随着客户端数量的不断增加、客户端功能的增加 ... -
rails 学习(转)
2011-08-17 11:15 8911. 书籍: rails 圣经: Agile Web De ... -
AJAX file uploads in Rails using attachment_fu and responds_to_parent
2011-08-12 17:32 561http://khamsouk.souvanlasy.com/ ... -
rails的REST特性简记(转)
2011-07-11 14:53 8651.关于REST的URL的详细讨论,参见《RESTful Ra ... -
ubuntu 10.10 rails 安装
2011-07-09 00:13 739http://floger.iteye.com/blog/93 ... -
rails rmagic安装问题 解决
2011-06-14 12:36 1018一开始手动下载imagemagick安装的,结果配置出现一些问 ... -
如何用nginx+passenger部署Rails(转)
2011-06-10 15:28 1742以前一直用apache+passenger ... -
rails + sqlserver 2005 分页 问题记录
2011-06-08 19:20 854都说sqlserver + rails 用着别扭,终于体会到了 ... -
centos 5.5 rails 安装 参考
2011-05-19 17:50 10371.安装gcc yum install gcc-c++ y ... -
centos 5.5 rails 安装 参考
2011-05-19 16:40 1130这二天部署一个项目,部署在Centos 5.5 下,本来用的u ... -
rails应用与多数据库的连接
2011-04-15 15:20 918rails与多数据库的连接有插件模式,也有原生模式,本文参考互 ...
相关推荐
《Rails入门教程一》是针对初学者的一份详尽指南,旨在帮助读者快速掌握Ruby on Rails框架的基础知识。Ruby on Rails(简称Rails)是一个基于Ruby语言的开源Web应用框架,遵循MVC(Model-View-Controller)架构模式...
本教程将带你走进Rails的世界,从零开始学习这个强大的框架。 一、Rails框架基础 Rails是David Heinemeier Hansson在2004年创建的,它引入了“Convention over Configuration”(约定优于配置)的理念,减少了...
**中文版Rails教程** Rails,全称为Ruby on Rails,是一个基于Ruby编程语言的开源Web应用程序框架,遵循MVC(模型-视图-控制器)架构模式。Rails以其“约定优于配置”(Convention over Configuration)和“Don't ...
这个“ruby on rails 教程源码”很可能是为了辅助学习者深入理解Rails的工作原理和最佳实践,通过实际操作来提升技能。 在Rails中,`sample_app-master`可能是一个示例应用程序的主目录,它包含了完整的项目结构。...
《Ruby on Rails Web开发学习实录》 第(2/2)分卷 PDF电子书 高清扫描版
- **敏捷开发与Rails:** 本书《Ruby on Rails教程》强调了Rails作为敏捷开发框架的优势。它旨在帮助开发者快速构建高质量的Web应用程序。 - **作者团队:** 本书由多位作者共同完成,包括Dave Thomas、David ...
在2014年的Rails教程中,你可能会学习到如何设置开发环境,安装Rails,创建新项目,理解Gemfile和Bundler的作用,以及如何使用Git进行版本控制。还会涉及控制器的创建、视图的渲染、模型的定义、数据库迁移以及表单...
本书算是最好的rails的与ruby的教程。。。全书共144M,此为part2,part1: http://download.csdn.net/detail/jiaoxiaogu/3835985
知识点2:Rails 安装 * 下载 Rails 2.0.2 版本 * 安装 Rails * 检查 Rails 版本 知识点3:Mongrel 安装 * 下载 Mongrel 1.1.4 版本 * 安装 Mongrel * 安装所需插件(gem plugin、daemons、fastthread、cgi_...
本书算是最好的rails的与ruby的教程。。。全书共144M,此为part1,还有part2
从给定的文件信息来看,我们正在探讨的是一本关于Ruby on Rails的书籍,书名为《Simply Rails2》,作者是Patrick Lenz。本书旨在为初学者提供深入理解Ruby on Rails框架的指南,从基础概念到高级主题均有涵盖,是...
rails本地安装包 需要你在安装了ruby一键安装包后安装,内有安装命令步骤。 第一部分在: http://download.csdn.net/source/498734