`
ywencn
  • 浏览: 87125 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

[翻译]<Rails guides> Rails缓存 // Caching with Ruby on Rails

阅读更多

原文:http://guides.rubyonrails.org/caching_with_rails.html


  翻译: 蜗牛 (http://ywencn.iteye.com)


Rails缓存总览:Caching with Rails: An overview


大家都会用到缓存。本指南将会告诉你如何减少数据库的访问次数并且在很短时间内向用户提供他们要的东西。



缓存基础 Basic Caching


这是一个不适用任何第三方插件的关于rails自带的3种类型的缓存技术的介绍。


在我们开始之前,确保 config/enviroments/*.rb 中的development.rb 中 config.action_controller.perform_caching 被设置为True,默认状态下, 开发环境和测试环境这行都被注释掉的,只有生产环境中是默认被打开的。


config.action_controller.perform_caching = true

 


1.1 页面缓存 Page Caching


页面缓存是Rails机制,允许只通过web服务器调用一个已经实际生成的页面,而不需要通过rails堆栈来呈现给用户,速度超级快。不幸的是,他不能提供很多情况下的支持,比如一个需要验证用户身份的页面的情况。并且在页面缓存中,web服务器直接调用文件系统种的一个页面缓存文件,因此还需要建立缓存失效策略,比如你更新了应该显示的页面内容等等。




那么,你要如何来使用这个超级快的缓存呢?简单,假设你有一个叫ProductsController的控制器 和 一个会列出所有商品的叫 list 的action。


class ProductsController < ActionController
caches_page :index

def index
end
end

 

当products/index第一次被访问的时候,Rails会创建一个名为index.html的文件,在那以后,web服务器会在下次收到products/index访问请求的时候直接调用那个静态文件。


默认情况下,页面缓存的文件夹在rails根目录的 public文件夹下。这个可以通过改变配置


setting config.action_controller.page_cache_directory
 

来设置。修改默认的/public存储位置有利于在你可能想他别的静态文件放在public中的时候避免文件名的命名冲突。修改这个设置的同时,还需要配置你的web服务器,否则他会找不到你的缓存文件。


页面缓存机制会为没有扩展名的页面请求自动的添加.html扩展名,来让web服务器很容易的找到这些页面。这个也可以通过改变配置文件来进行设置:


config.action_controller.page_cache_extension

 

为了在新添加商品后,让页面缓存失效,你可以像这样来写你的products控制器:


class ProductsController < ActionController

caches_page :index

def index; end

def create
expire_page :action => :index
end

end


如果你想要一个更复杂的缓存失效计划,你可以使用缓存清道夫(sweepers)来让当缓存原来的对象改变时让缓存过期。这个在在Sweepers那节有讲述。


注意:页面缓存会无视所有的参数,所以 /products/list?page=1 在缓存文件系统中生成的文件是 /products/list.html。如果有人访问/proucts/list?page=2 ,那么他得到的结果和 page=1 是一样的。所以你应当注意页面缓存中URL使用GET参数的情况。


1.2 动作缓存 Action Caching


不能使用页面缓存的情况之一就是你不能将其用于那些需要身份验证的页面。这个时候你就可以使用动作缓存。动作缓存的工作原理和页面缓存差不多,只是web请求会从web服务器传递给Rails解析器和Action Pack,这样以来过滤器就可以在缓存被调用以前生效。这样你就可以使用身份验证和别的一些限制,同时输出缓存副本。


清除Action缓存和页面缓存的方式完全相同。


比方说,你只是想验证用户编辑或者创建一个产品,但是仍然缓存这些页面:


class ProductsController < ActionController

before_filter :authenticate, :only => [ :edit, :create ]
caches_page :index
caches_action :edit

def index; end

def create
expire_page :action => :index
expire_action :action => :edit
end

def edit; end

end


你还可以使用 :if(或者 :unless) 来传递一个 指定何时应缓存 action 的 Proc。此外,你还可以使用 :layout=> false 使缓存没有布局,这样以来布局模板中的动态信息比如已经登录的用户的用户名或者是购物车中商品的数量可以被保留。使用这项功能需要Rails2.2及更高版本。


你可以传递一个:cache_option选项来修改默认的缓存路径。这会直接传递给 ActionCachePath.path_for 。这对于有多个可用路由并且需要做不同缓存的情况非常有用。如果指定了一个代码块,那么他将被当前控制器实例所调用。


Nín kěyǐ tōngguò chuándì yīgè:Cache_path xuǎnzé mòrèn cāozuò gāosù huǎncún lùjìng.Zhè jiāng zhíjiē chuándì gěi ActionCachePath.Path_for.Zhè shì fēicháng fāngbiàn de duō, yīng jǐn kěnéng huǎncún bùtóng de lùxiàn xíngdòng.Rúguǒ gěi chū yīgè kuài, tā bèi chēng wèi yǔ dāngqián kòngzhì qì shílì.

最后,如果你在使用 memcache,你还可以传递 :expires_in 。事实上,所以 caches_action 没用到的参数都会被发送给底层缓存存储。


1.3 片断缓存 Fragment Caching



如果我们只需要把一个页面或者一个action的内容缓存起来然后发给用户那该多好。不幸的是,动态web应用通常都由很多个部份组成,他们具有不同的页面特征。为了解决此类的动态创建的页面,在页面的不同部份需要建立不同的缓存和缓存失效机制。Rails提供了一种叫片断缓存的东西来解决这个问题。



片断缓存允许视图逻辑的一个被缓存块包裹起来的片断形成一个缓存,在下次受到请求的时候发送出去。


举个例子,如果你想即时的显示你的网站中的全部订单并且不想在那个部份使用缓存,但是想缓存页面上列出全部商品的列表,你可以使用这段代码:


<% Order.find_recent.each do |o| %>
<%= o.buyer.name %> bought <% o.product.name %>
<% end %>

<% cache do %>
All available products:
<% Product.find(:all).each do |p| %>
<%= link_to p.name, product_url(p) %>
<% end %>
<% end %>


我们示例中的缓存块将绑定到调用他的那个action并且和acion缓存放在相同的路径下。这意味着如果你的每个action中有多个缓存片断,你就应当为cache调用提供一个 action_suffix


<% cache(:action => 'recent', :action_suffix => 'all_prods') do %>
All available products:
<% Product.find(:all).each do |p| %>
<%= link_to p.name, product_url(p) %>
<% end %>
<% end %>

你可以使用expire_fragment 来使缓存过期:


expire_fragment(:controller => 'products', :action => 'recent',   :action_suffix => 'all_prods


如果你不希望缓存块绑定到调用它的那个action,也可以使用全局标示片段。像这样,通过一个键来调用缓存方法:


<% cache(:key => ['all_available_products', @latest_product.created_at].join(':')) do %>
All available products:
<% end %>


这个片段就可以在Products控制器的所有actions中使用键来调用并且使用相同的方法来使之失效:


expire_fragment(:key => ['all_available_products', @latest_product.created_at].join(':'))
 

1.4  扫地大妈 Sweepers


缓存扫地大妈是一种允许你把代码中的一大堆 expire_{page,action.fragment}调用放在一起的机制。这是通过把所有的清除缓存内容的工作都移动到ActionController::Cacheing::Sweeper 类种来实现的。这个类是一个通过回调监控一个对象状态改变的监视器。当发生改变的时候,他就通过那个对象的前后过滤器或后置过滤器来让那个对象的缓存失效。


继续我们的Product控制器示例,我们可以像这样通过sweeper来重写他:


class StoreSweeper < ActionController::Caching::Sweeper
# This sweeper is going to keep an eye on the Product model
observe Product

# If our sweeper detects that a Product was created call this
def after_create(product)
expire_cache_for(product)
end

# If our sweeper detects that a Product was updated call this
def after_update(product)
expire_cache_for(product)
end

# If our sweeper detects that a Product was deleted call this
def after_destroy(product)
expire_cache_for(product)
end

private
def expire_cache_for(record)
# Expire the list page now that we added a new product
expire_page(:controller => '#{record}', :action => 'list')

# Expire a fragment
expire_fragment(:controller => '#{record}',
:action => 'recent', :action_suffix => 'all_products')
end
end
 

The sweeper has to be added to the controller that will use it. So, if we wanted to expire the cached content for the list and edit actions when the create action was called, we could do the following:


扫地大妈已经被添加到那些会用到他的控制器中。所以,如果我们想要在create action 被调用的时候,清除list 和 edit 两个action的缓存内容,我们可以这样做:


class ProductsController < ActionController

before_filter :authenticate, :only => [ :edit, :create ]
caches_page :list
caches_action :edit
cache_sweeper :store_sweeper, :only => [ :create ]

def list; end

def create
expire_page :action => :list
expire_action :action => :edit
end

def edit; end

end
 

1.5 SQL缓存   SQL Caching


查询缓存是一个对每个查询返回的数据集进行缓存的一个Rails特色。如果Rails在本次请求种再次发起了相同的查询,他就会使用被缓存起来的结果集而不需要再次对数据库发出请求。


class ProductsController < ActionController

before_filter :authenticate, :only => [ :edit, :create ]
caches_page :list
caches_action :edit
cache_sweeper :store_sweeper, :only => [ :create ]

def list
# Run a find query
Product.find(:all)

...

# Run the same query again
Product.find(:all)
end

def create
expire_page :action => :list
expire_action :action => :edit
end

def edit; end

end
 

在上面的list 这个action,Product.find(:all)返回的结果会被缓存起来,下次再发起这个finder调用的时候就不需要再次读取数据库了。


1.6  缓存存储 Cache Stores


Rails 提供为action 缓存 和 片段缓存的数据提供很不同的存储方法。页面缓存通常是被存在磁盘上的。


Rails2.1 以及更新版本提供了可以缓存字符串的 ActiveSupport::Cache::Store 。一些像MemoryStore的缓存存储可以缓存任意的Ruby对象,但不要指望每个缓存存储都可以这样做。


钢轨 2.1 和以上提供 ActiveSupport::Cache::Store,可用于缓存的字符串。 一些缓存存储像 MemoryStore 的实现,能够缓存任意的 Ruby 对象,但不要指望能够这样做的每个缓存存储区。


默认的Rails包含的缓存存储提供了:


1) ActiveSupport::Cache::MemoryStore:一种用相同进程把所有的东西存储到内存中的缓存存储实现。如果你运行了多个Ruby on Rails服务进程(比如 你在同时使用 mongrel_cluser 或者 Phusion Passenger),然后这意味着你的Rails服务进程实例不能够彼此共享缓存数据。如果你的应用不执行手动的缓存失效(如比你用缓存键),然后使用MemoryStore是可以的。否则,仔细考虑是否您应该使用此缓存存储。


MemoryStoreis 不仅仅可以存储字符串,而且也可以存储任意Ruby对象。MemoryStoreis不是安全线程。如果你需要安全线程,请改用SynchronizedMemoryStore 的内容。


ActionController::Base.cache_store = :memory_store


2) ActiveSupport::Cache::FileStore:缓存数据存放在磁盘上。这个默认的存储,路径是/tmp/cache. 在所有的环境下都工作得很好,并且允许所有的线程从相同应用程序文件夹中访问缓存内容。如果/tmp/cache不存在,那么默认的存储方式变成memoryStore.


ActionController::Base.cache_store = :file_store, "/path/to/cache/directory"
 

3) ActiveSupport::Cache::DRbStore: 缓存的数据存储在一个所有服务可以与之通信的单独的共享DRb进程中。这适用于所有环境,并为所有进程保持一个缓存。但是这就要求你运行并管理一个单独的DRb线程。


ActionController::Base.cache_store = :drb_store, "druby://localhost:9192"
 

4) MemCached store: Works like DRbStore, but uses Danga’s MemCache instead. Rails uses the bundled memcached-client gem by default. This is currently the most popular cache store for production websites.


4) MemCached store:


未完---待续

分享到:
评论

相关推荐

    举例理解Ruby on Rails的页面缓存机制

    在 Ruby on Rails 中,页面缓存是一种优化性能的技术,尤其适用于那些内容相对静态或者对用户个性化要求不高的网页。页面缓存的工作原理是将动态生成的 HTML 页面直接保存到服务器的文件系统中,后续的相同请求可以...

    ruby on rails 3 tutorial.pdf

    《Ruby on Rails 3 Tutorial》是一本专门为初学者设计的指南,旨在帮助读者快速掌握Ruby on Rails这一强大的Web开发框架。Ruby on Rails(简称Rails)是基于Ruby语言的一个开源框架,它采用MVC(Model-View-...

    Beginning Ruby on Rails

    Ruby on Rails is the revolutionary online programming tool that makes creating functional e-commerce web sites faster and easier than ever. With the intuitive, straightforward nature of Ruby and the ...

    Ruby On Rails开发实例-源代码

    "Ruby中文文档"可能包括了对Ruby语法、类、对象、模块、方法等基础知识的介绍,以及Rails框架的核心概念,如路由(Routing)、控制器(Controllers)、视图(Views)、模型(Models)、ActiveRecord、助手方法...

    Agile Web Development with Rails 4

    Ruby on Rails helps you produce high-quality, beautiful-looking web applications quickly. You concentrate on creating the application, and Rails takes care of the details., Tens of thousands of ...

    Ruby Rails 3 Linda

    Ruby on Rails,简称Rails,是由David Heinemeier Hansson基于Ruby语言开发的一个开源Web应用程序框架。Rails遵循MVC(模型-视图-控制器)架构模式,致力于“约定优于配置”和“Don't Repeat Yourself”(DRY)的...

    Ruby-ActionPack的Action缓存在Rails40中从核心移除

    在Ruby on Rails框架中,ActionPack是一个核心组件,它包含了控制器、路由以及处理HTTP请求和响应的工具。Action Cache是ActionPack的一部分,主要用于提高Web应用的性能,通过缓存Action的输出来避免重复执行相同的...

    RAILS2.1的中文版资料

    《RAILS2.1的中文版资料》是一份针对Ruby on Rails 2.1版本的详细介绍文档,由Carlos Brando和Marcos Tapajós共同编写,并由中国Rails社区成员翻译成中文版。该文档详细介绍了Rails 2.1版本中引入的新特性和改进之...

    Rails.Angular.Postgres.and.Bootstrap.2nd.Edition

    This book covers Postgres 9.5, Rails 5, and Ruby 2.3. You should have some experience with basic Rails concepts and a cursory understanding of JavaScript, CSS, and SQL, but by no means need to be an ...

    rubyonrails

    Ruby on Rails(简称Rails)是一种基于Ruby编程语言的开源Web应用程序框架,它遵循Model-View-Controller(MVC)架构模式。Rails强调“约定优于配置”(Convention over Configuration)和“Don't Repeat Yourself”...

    cakephp-2.3.0.rar_ruby rails php

    在性能优化上,CakePHP 2.3.0引入了缓存策略,如使用Memcached或APC进行数据缓存,以及视图碎片(View Caching)和查询缓存,这些都有助于提升应用的响应速度。 在开发工具和调试方面,CakePHP 2.3.0提供了丰富的...

    rails查询学习笔记

    9. **Caching**:为了提高查询效率,Rails支持查询缓存,可以缓存特定查询的结果,避免重复执行相同的数据库操作。 10. **SQL注入防范**:Rails通过绑定参数的方式防止SQL注入,如`Model.where(id: params[:id])`,...

    Rails_Recipes_with_Source_Code

    《Rails Recipes with Source Code》是一本专注于Ruby on Rails框架实践技巧和源代码解析的书籍。Rails是基于Ruby语言的Web开发框架,以其“约定优于配置”(Convention over Configuration)的理念和“开发人员的...

    rails-documentation-1-2-1.zip

    3. **Caching**:学习 Rails 的缓存策略,包括页面缓存、片段缓存和查询缓存,以提高应用程序性能。 阅读这个 "rails-documentation-1-2-1.chm" 文件,开发者可以深入理解 Rails 1.2.1 版本的核心特性,提升自己的 ...

    Pragmatic.Bookshelf.Advanced.Rails.Recipes.May.2008

    这本书主要面向已经熟悉Ruby on Rails基础的开发者,旨在通过一系列实用的解决方案和技巧,提升他们在Rails框架下的开发能力。 在Rails框架中,开发者可以快速构建高效、灵活的Web应用。本书深入探讨了Rails的高级...

    Rails, Angular, Postgres, and Bootstrap(Pragmatic,2016)

    Take a holistic view of full-stack development to create usable, high-performing applications, and learn to use these technologies effectively in a Ruby on Rails environment. Rails is a great tool ...

    cake php框架 v1.2(仿rails)

    最开始从Ruby On Rails框架里得到灵感。程序员可使用它来快速创建的Web应用程序。我们的首要目的是使你以一种预置的快速且不失灵活性的方式开展工作。 为什么是CakePHP? CakePHP有多个特点,这些特点让CakePHP成为...

Global site tag (gtag.js) - Google Analytics