>

Rails中的缓存机制,多少个加速Ruby

- 编辑:www.bifa688.com -

Rails中的缓存机制,多少个加速Ruby

有了页面缓存,Rails 就可以不再加入。在某种程度上,那是件好事,因为你的确能够收获优良的习性。Rails 只需创立 HTML 页面,将其放入目录,之后,就能够置之于脑后。从这时起,就由应用服务器管理那一个页面,且页面进入应用服务器无需任何循环。从性质的角度来讲,页面缓存真是天赐之福。

几个加速Ruby on Rails的编制程序技能,rubyrails

Ruby 语言常以其灵活性为人所称道。正如 Dick Sites 所言,您可以“为了编制程序而编制程序”。Ruby on Rails 扩大了主导 Ruby 语言,但就是 Ruby 本人使得这种扩大成为了恐怕。Ruby on Rails 使用了该语言的狡猾,那样一来,无需太各种板或附加的代码就能够轻巧编写中度结构化的主次:不须求附加职业,就可以赢得大批量规范的作为。即使这种轻巧自由的作为并不总是完美的,但归根结蒂你可以不须求太多职业就足以拿走过多好的架构。

譬喻,Ruby on Rails 基于模型-视图-调控器(Model-View-Controller,MVC)格局,那象征大多数Rails 应用程序都得以清晰地分成七个部分。模型部分含有了管理应用程序数据所需的行为。日常,在一个Ruby on Rails 应用程序中,模型和多少库表之间的关联是 1:1;Ruby on Rails 暗中认可使用的指标关联映射(ORM)ActiveRecord 担负处理模型与数据库的并行,那意味 Ruby on Rails 程序日常都持有(尽管部分话)很微量的 SQL 代码。第三个部分是视图,它富含创立发送至用户的输出所必要的代码;它日常由 HTML、JavaScript 等整合。最终的一个部分是调节器,它未来自用户的输入转换为不易的模子,然后使用极度的视图突显响应。

Rails 的提出者经常都乐于将其易用性方面包车型客车加强归功于 MVC 范型 — 以及 Ruby 和 Rails 二者的别的界分表征,并称异常少有技士能够在不够长的时日内创立越来越多的法力。当然,那意味投入到软件开拓的本金将能够发出更加的多的商业价值,因此Ruby on Rails 开荒愈发流行。

而是,最初的开垦耗费并不是业务的整个,还或者有其余的接轨资金供给缅怀,例如应用程序运营的爱慕资金财产和硬件费用。Ruby on Rails 开荒职员平日会采取测量试验和其他的快捷开垦本领来下滑维护开销,不过那样一来,很轻巧忽略具有大量数额的 Rails 应用程序的可行运营。即便 Rails 能够简化对数据库的拜访,但它并不总是能够如此有效。
Rails 应用程序为啥运营缓慢?

Rails 应用程序之所以运营缓慢,在那之中有多少个很基本的由来。第多个原因很简短:Rails 总是会做一些如若为您加快开拓。平日,这种假设是不错而有帮忙的。可是,它们并不总能有益于质量,并且还大概会促成财富选用的功用低下 — 特别是数据库财富。

比方,使用同样 SELECT * 的三个 SQL 语句,ActiveRecord 会暗中同意选项查询上的具有字段。在富有一系列的列的境况下 — 非常是当有个别字段是惊天动地的 VARCHA凯雷德 或 BLOB 字段时 — 就内部存款和储蓄器使用和总体性来讲这种作为很有标题。

另二个领会的挑衅是 N 1 难点,本文将对此张开详尽的追究。那会导致众多小查询的实施,而不是三个十足的大查询。比方,ActiveRecord 无从知道一组父记录中的哪三个会呈请贰个子记录,所以它会为各类父记录生成三个子笔录查询。由于每查询的负载,这种表现将招致显然的质量难点。

其它的挑战则越来越多地与 Ruby on Rails 开垦职员的付出习于旧贯和态势相关。由于 ActiveRecord 能够让那样众多的天职变得轻巧,Rails 开垦人士平日会产生“SQL 不如何” 的一种态度,纵然在更适合利用 SQL 的时候,也会防止SQL。创制和处理数据巨大的 ActiveRecord 对象的进程会极度缓慢,所以在有一点情状下,直接编写叁个不须要实例化任何对象的 SQL 查询会越来越快些。

鉴于 Ruby on Rails 常被用来下落开荒团队的局面,又由于 Ruby on Rails 开采人士平常都会实施铺排和维护生产中的应用程序所需的部分系统管理任务,由此若对应用程序的条件知之甚少,就很恐怕出标题。操作系统和数据库有希望未被正确安装。举个例子,固然并不最优,MySQL my.cnf 设置平时在 Ruby on Rails 安排内保存它们的暗许设置。其余,恐怕还有恐怕会缺少丰富的监察和控制和准星测验工具来提供品质的漫长情况。当然,那并不是在质问Ruby on Rails 开垦职员;那是非专门的学业化导致的结局;在稍微情状下,Rails 开采人士有十分的大只怕是这多少个世界的学者。

末尾二个题目是 Ruby on Rails 鼓励开辟职员在本土遭遇中展开开采。这么做有多少个好处 — 比方,开采延迟的削减和布满性的拉长 — 但它并不代表你能够因为职业站规模的回降而只管理有限的数据集。他们怎么样支付以及代码将被布署于何处之间的异样大概会是四个大主题素材。固然你在贰脾性质特出的轻载本地服务器上管理小范围的多寡已经十分长一段时间,也会意识对于拥挤堵塞的服务器上的巨型数据此应用程序会有很领悟的属性难点。

本来,Rails 应用程序具备质量难题的来由恐怕有无尽。查出 Rails 应用程序有什么潜在质量难题的特级艺术是,利用能为您提供可再度、正确衡量的确诊工具。

检查实验性能难点

最好的工具之一是 Rails 开荒日志,它一般位于每一种开辟机器上的 log/development.log 文件内。它抱有种种综合指标:响应诉求所费用的总时间、开支在数据库内的时刻所占的比重、生成视图所花时间的比例等。其它,还会有局地工具可用来深入分析此日志文件,比方development-log-analyzer。

在生养之间,通过查阅 mysql_slow_log 能够找到大多有价值的音信。更为周详的介绍超越了本文的座谈范围,越来越多音信方可在 参照他事他说加以考查资料 部分找到。

中间贰个最有力也是最最可行的工具是 query_reviewer 插件(参见 参谋资料)。这几个插件可浮今后页面上有多少查询在施行以及页目生成要求多久。并且它还大概会活动解析ActiveRecord 生成的 SQL 代码以便发掘潜在难点。举个例子,它能找到不采取 MySQL 索引的询问,所以一旦你忘记了目录三个最首要的列并因此导致了品质难点,那么你将能很轻松地找到这么些列(有关 MySQL 索引的更加的多新闻,参见 参照他事他说加以考察资料)。此插件在三个弹出的 <div>(只在支付形式下可知)中显得了装有那类消息。

最后,不要遗忘行使类似 Firebug、yslow、Ping 和 tracert 那样的工具来检查验质量量难点是发源于互连网大概财富加载难题。

接下去,让大家来看现实的一对 Rails 品质难题及其化解方案。

N 1 查询难题

N 1 查询难点是 Rails 应用程序最大的标题之一。举例,清单 1 内的代码能生成多少查询?此代码是二个轻易易行的循环,遍历了三个假诺的 post 表内的有着 post,并展示 post 的项目和它的主体。
清单 1. 未优化的 Post.all 代码

<%@posts = Post.all(@posts).each do |p|%> 
 <h1><%=p.category.name%></h1>
 <p><%=p.body%></p>
<%end%>

答案:上述代码生成了贰个询问外加 @posts 内的每行五个查询。由于每查询的负载,这恐怕会成为五个十分的大的挑衅。罪魁祸首是对 p.category.name 的调用。那么些调用只使用于该特定的 post 对象,而不是所有@posts 数组。幸亏,通过行使即时加载,我们能够修复那些问题。

眼看加载 意味着 Rails 将自动试行所需的查询来加载任何特定子对象的指标。Rails 将选用叁个 JOIN SQL 语句或三个实施四个查询的国策。然则,假若钦赐了将在利用的全体子对象,那么将恒久不会招致 N 1 的景况,在 N 1 情状下,三个循环往复的种种迭代都会生成额外的三个询问。清单 2 是对 清单 1 内代码的纠正,它使用了马上加载来防止 N 1 难题。
清单 2. 用当下加载优化后的 Post.all 代码

<%@posts = Post.find(:all, :include=>[:category]
 @posts.each do |p|%> 
 <h1><%=p.category.name%></h1>
 <p><%=p.body%></p>
<%end%>

该代码最多生成多少个查询,而不论在此 posts 表内有微微行。

当然,并不是装有情状都那样简约。管理复杂的 N 1 查询情况供给越多的做事。那么做这么多努力值得么?让我们来做一些飞跃的测验。

测试 N 1

运用清单 3 内的脚本,能够开采查询能够高达 — 多慢 — 或多快。 清单 3 体现了怎么着在一个单独脚本中利用 ActiveRecord 来树立一个数据库连接、定义表并加载数据。然后,能够行使 Ruby 的放到基准测验库来查阅哪一种格局越来越快,快多少。
清单 3. 当下加载基准测验脚本

require 'rubygems'
require 'faker'
require 'active_record'
require 'benchmark'

# This call creates a connection to our database.

ActiveRecord::Base.establish_connection(
 :adapter => "mysql",
 :host   => "127.0.0.1",
 :username => "root", # Note that while this is the default setting for MySQL,
 :password => "",   # a properly secured system will have a different MySQL
              # username and password, and if so, you'll need to
              # change these settings.
 :database => "test")

# First, set up our database... 
class Category < ActiveRecord::Base
end

unless Category.table_exists?
 ActiveRecord::Schema.define do
 create_table :categories do |t|
  t.column :name, :string
 end
 end 
end

Category.create(:name=>'Sara Campbell's Stuff')
Category.create(:name=>'Jake Moran's Possessions')
Category.create(:name=>'Josh's Items')
number_of_categories = Category.count

class Item < ActiveRecord::Base 
 belongs_to :category 
end

# If the table doesn't exist, we'll create it.

unless Item.table_exists?
 ActiveRecord::Schema.define do
 create_table :items do |t|
  t.column :name, :string
  t.column :category_id, :integer 
 end
 end 
end

puts "Loading data..."

item_count = Item.count
item_table_size = 10000

if item_count < item_table_size
 (item_table_size - item_count).times do
 Item.create!(:name=>Faker.name, 
         :category_id=>(1 rand(number_of_categories.to_i)))
 end
end

puts "Running tests..."

Benchmark.bm do |x| 
 [100,1000,10000].each do |size| 
 x.report "size:#{size}, with n 1 problem" do 
  @items=Item.find(:all, :limit=>size)
  @items.each do |i| 
  i.category
  end 
 end 
 x.report "size:#{size}, with :include" do 
  @items=Item.find(:all, :include=>:category, :limit=>size)
  @items.each do |i| 
  i.category
  end 
 end 
 end 
end

其一剧本使用 :include 子句测量检验在有和尚未霎时加载的动静下对 100、1,000 和 10,000 个对象举办巡回操作的进程如何。为了运营此脚本,您可能须要用适合于你的地点情况的参数替换此脚本最上部的这么些数据库连接参数。其余,供给制造四个名字为test 的 MySQL 数据库。最后,您还亟需 ActiveRecord 和 faker 那三个gem,二者可经过运维 gem install activerecord faker 获得。

在作者的机器上运营此脚本生成的结果如清单 4 所示。
清单 4. 当下加载的法规测验脚本输出

-- create_table(:categories)
 -> 0.1327s
-- create_table(:items)
 -> 0.1215s
Loading data...
Running tests...
  user   system   total    real
size:100, with n 1 problem 0.030000  0.000000  0.030000 ( 0.045996)
size:100, with :include 0.010000  0.000000  0.010000 ( 0.009164)
size:1000, with n 1 problem 0.260000  0.040000  0.300000 ( 0.346721)
size:1000, with :include 0.060000  0.010000  0.070000 ( 0.076739)
size:10000, with n 1 problem 3.110000  0.380000  3.490000 ( 3.935518)
size:10000, with :include 0.470000  0.080000  0.550000 ( 0.573861)

在具备景况下,使用 :include 的测验总是更为便捷 — 分别快 5.02、4.52 和 6.86 倍。当然,具体的出口取决于你的特定情景,但迅即加载可眼看导致分明的性质改正。

嵌套的登时加载

万一您想要引用一个嵌套的关系 — 关系的关系,又该如何呢? 清单 5 呈现了那样三个广泛的状态:循环遍历全体的 post 并展现小编的图像,个中Author 与 Image 是 belongs_to 的关系。
清单 5. 嵌套的立时加载用例

@posts = Post.all 
@posts.each do |p| 
 <h1><%=p.category.name%></h1>
 <%=image_tag p.author.image.public_filename %> 
 <p><%=p.body%> 
 <%end%>

此代码与事先同一亦遭到了同一的 N 1 难题,但修复的语法却从不那么显明,因为此地所接纳的是事关的涉嫌。那么什么样工夫即时加载嵌套关系吗?

毫无疑问的答案是使用 :include 子句的哈希语法。清单 6 给出了应用哈希语法的四个嵌套的立即加载。
清单 6. 嵌套的马上加载消除方案

@posts = Post.find(:all, :include=>{ :category=>[],
                    :author=>{ :image=>[]}} )
@posts.each do |p| 
 <h1><%=p.category.name%></h1>
 <%=image_tag p.author.image.public_filename %> 
 <p><%=p.body%> 
 <%end%>

正如您所见,您可以嵌套哈希和数组实量(literal)。请留意在本例中哈希和数组之间的惟一不一样是哈希能够涵盖嵌套的子条款,而数组则不能够。不然,二者是同样的。

直接的当即加载

并非全部的 N 1 难题都能很轻便地开掘到。举个例子,清单 7 能生成多少查询?
清单 7. 直接的当即加载示例用例

 <%@user = User.find(5)
  @user.posts.each do |p|%>  
   <%=render :partial=>'posts/summary', :locals=>:post=>p
   %> <%end%>

理所必然,决定查询的多少须要对 posts/summary partial 有所精通。清单 8中呈现了这几个 partial。
清单 8. 直接马上加载 partial: posts/_summary.html.erb

 <h1><%=post.user.name%></h1>

不佳的是,答案是 清单 7 和 清单 8 在 post 内每行生成贰个附加查询,查找用户的名字 — 纵然 post 对象由 ActiveRecord 从一个已在内部存款和储蓄器中的 User 对象自动生成。简言之,Rails 并不可能关联子记录与其父记录。

修补方法是选取自援引的登时加载。基本上,由于 Rails 重载由父记录生成的子记录,所以要求立刻加载这么些父记录,就不啻父与子记录之间是一点一滴分离的涉及一样。代码如清单 9 所示。
清单 9. 直接的霎时加载化解方案

 <%@user = User.find(5, :include=>{:posts=>[:user]})
 ...snip...

固然有悖于直觉,但这种技巧与上述手艺的干活原理大概相像。可是,很轻松接纳这种本事进行过多的嵌套,特别是在系统结构复杂的场合下。简单的用例辛亏,比如清单 9 内所示的,但复杂的嵌套也会出难题。在一部分情况下,过多地加载 Ruby 对象有非常大希望会比拍卖 N 1 难题还要缓慢 — 特别是当每一个对象并未被全部树遍历时。在该种意况下,N 1 难点的其余消除方案或然更进一步适合。

一种方法是运用缓存本事。Rails V2.1 内置了简要的缓存访问。使用 Rails.cache.read、 Rails.cache.write 及相关方法,可以轻巧成立本人的粗略缓存机制,并且后端能够是三个总结的内部存款和储蓄器后端、二个基于文件的后端或四个布满式缓存服务器。在 参照他事他说加以考查资料 部分能够找到关于 Rails 内置缓存帮助的越来越多音讯。但你没有需求创建协调的缓存消除方案;您可以应用二个预置的 Rails 插件,比方 Nick Kallen 的 cache money 插件。那一个插件提供了 write-through 缓存并以 Instagram 上使用的代码为底蕴。越来越多音讯参见 参照他事他说加以调查资料。

当然,并不是怀有的 Rails 难点都与查询的数量有关。

Rails 分组和集结计算

您大概遇见的一个主题素材是在 Ruby 所做的工作本应由数据库实现。那考验了 Ruby 的无敌程度。很难想象在没有别的重大激励的气象下大家会自愿在 C 中重新达成其数据库代码的各类部分,但很轻松在 Rails 内对 ActiveRecord 对象组开始展览类似的计算。可是,Ruby 总是要比数据库代码慢。所以请不要采纳纯 Ruby 的办法试行总括,如清单 10 所示。
清单 10. 推行分组计算的不得法方法

 all_ages = Person.find(:all).group_by(&:age).keys.uniq
 oldest_age = Person.find(:all).max

相反,Rails 提供了一多种的分组和聚合函数。能够像清单 11 所示的那样采取它们。
清单 11. 推行分组总结的不错方法

 all_ages = Person.find(:all, :group=>[:age]) 
 oldest_age = Person.calcuate(:max, :age)

ActiveRecord::Base#find 有多量选项可用于模仿 SQL。越来越多音信方可在 Rails 文书档案内找到。注意,calculate 方法可适用于受数据库帮助的任何有效的聚合函数,比如 :min、:sum 和 :avg。其余,calculate 可以承受多少实参,譬喻 :conditions。查阅 Rails 文书档案以获取更详实的新闻。

可是,并不是在 SQL 内能做的持有专业在 Rails 内也能做。假若插件非常不够,能够应用定制 SQL。

用 Rails 定制 SQL

假使有那样二个表,内含人的事情、年龄以及在过去一年中涉嫌到他们的事故的多少。能够接纳二个定制 SQL 语句来索求此新闻,如清单 12 所示。
清单 12. 用 ActiveRecord 定制 SQL 的例子

sql = "SELECT profession,
       AVG(age) as average_age, 
       AVG(accident_count) 
     FROM persons 
    GROUP 
      BY profession"

Person.find_by_sql(sql).each do |row|  
 puts "#{row.profession}, " <<
    "avg. age: #{row.average_age}, " <<
    "avg. accidents: #{row.average_accident_count}"
end

那几个剧本应该能生成清单 13 所示的结果。
清单 13. 用 ActiveRecord 定制 SQL 的输出

 Programmer, avg. age: 18.010, avg. accidents: 9
 System Administrator, avg. age: 22.720, avg. accidents: 8

自然,那是最简便的例证。您能够团结想象一下怎么着能将此例中的 SQL 扩大成贰个有些复杂的 SQL 语句。您还足以行使 ActiveRecord::Base.connection.execute 方法运营其余门类的 SQL 语句,比方ALTEHighlander TABLE 语句,如清单 14 所示。
清单 14. 用 ActiveRecord 定制非查找型 SQL

 ActiveRecord::Base.connection.execute "ALTER TABLE some_table CHANGE COLUMN..."

好多的形式操作,举个例子增添和删除列,都足以动用 Rails 的嵌入方法成功。但假使急需,也得以使用举办放肆 SQL 代码的技巧。

结束语

与富有的框架同样,假使寥寥无几加小心和理会,Ruby on Rails 也会遭到质量难点。所幸的是,监察和控制和修复这个主题素材的手艺相对轻巧且易学,而且即正是目眩神摇的标题,只要有耐心并对质量难点的源头有所驾驭,也是足以化解的。

on Rails的编程能力,rubyrails Ruby 语言常以其灵活性为人所称道。正如 狄克 Sites 所言,您可以“为了编制程序而编制程序”。Ruby on Rails...

多少个现象

自己也珍视页面缓存,Rails 使之轻巧利落。只需选拔一行代码就足以启用缓存。假使再参预一些代码,就会通过轻松地删除文件操作或采用Rails 较高层的 API 终止缓存。这里存在二个标题。并不是每一种网址都能运用页面缓存。借使页面上的数据会根据访问它的用户而更动,那么就不可能开始展览页面缓存。而且,假若很难判断页面哪天到期结束,就能发觉页面缓存的渴求太过苛刻。

第一,让本人先来带你浏览多少个 ChangingThePresent.org 中的页面吗。笔者将体现站点中多少个须要缓存的地方。然后,再提出我们为内部各类地方所做出的接纳以及为促成那一个页面所使用的代码或宗旨。特别会注重研商如下内容:

例如,大概在各种页面上,ChangingThePresent.org(参阅 侧栏)都有少数用户数据是基于当下报到的用户而退换的。图 1 来得了大家最新主页的一局地。(大家直接在力图健全它,所以它有相当大可能率会转移。)那些页面显示出的题材相对轻松。假若能看清用户是还是不是早就报到,就足以用 Flash、JavaScript、DHTML 或任何别的依据浏览器的代码动态定制视图。您会发觉已报到的用户能够登出系统或查看其布署文件,而已登出的用户则能够登记或再一次登陆。
图 1. ChangingThePresent.org 上的登陆和发布视图

  •     全静态页面
  •     差不离无变化的全动态的页面
  •     动态页面片段
  •     应用程序数据

图片 1

先来探视静态页面。差相当少各样站点都会有静态页面,如图 1 所示,个中还也可以有大家的条款和规范。能够经过单击 register 然后再选用是或不是接受用户协商来浏览相应页面。对于 ChangingThePresent 来讲,大家随后页中删除了具备动态内容以便 Apache 能够对它举行缓存。依照大家 Apache 中布置的平整,那些剧情永恒都不会由 Rails 服务器生成。由此,作者一向无需对其思考 Rails 缓存。
图 1. 用户协议

图 2 呈现了略微某些高级的用户数据视图,大家的站点就利用了那么些视图。图 第22中学的多少个视图有十分大的不相同。为了管理页面缓存,笔者必须先消除全体的出入。对于每个已报到的用户,小编都必须替换掉页面包车型地铁登出内容,使之展现登入用户的登入ID 和用户图片。缓存这么些故事情节会带来另一层面包车型大巴挑衅,因为每一个用户的数额都不尽同样。
图 2. 八个完全不相同的视图

图片 2

图片 3

 接下来,再来看看全动态页面。理论上讲,ChangingThePresent 能够有局地动态创设的页面,可是那些页面一般没多少变化。由于大约全体页面都会显得用户是不是登入,由此大家并不怎么关切这种缓存。

这种状态并非 ChangingThePresent.org 所独有。如若须求本性化用户体验,那么不可修改的 Rails 页面缓存的运用就能够遭到限制。但假设定制相当的少,那么实际上还能很轻易地缓存这一个页面包车型客车。

再下来,看看页面分段缓存。图 2中所示的主页原本是全然静态的,以往,有一部分要素变为了动态的。每一日,页面都会显得一文山会海礼物,这几个礼品有的是随机选的,有的则由大家的总指挥选定。请小心在标题为 “A Few of our Special Gifts for Mother's Day” 节下的这多少个礼物,同一时候也请留意在最右面展现为 “login.” 的十分链接。此链接取决于用户是还是不是登入。大家不可能缓存整个页。页面每日只好改造三次。
图 2. 主页

焚薮而田那些难点的法子繁多。我更赞成于选拔如下那么些手艺:

图片 4

  •     在 Rails 框架的牢笼之内,裁撤页面缓存并利用段缓存代替他。
  •     先加载页面包车型地铁大部,然后采取 JavaScript 和 Ajax 加载该页面极小的动态部分。服务器端代码能够检验用户是或不是登入,然后用 Ajax 展现合适的有个别。
  •     将某个用户景况(举例用户是不是已登陆)存款和储蓄在客户端的 cookie 中。然后,依照 cookie 的故事情节,使用 JavaScript 动态改造页面包车型大巴外观。

 最终再考虑应用程序。除非是在 15 年从前开始展览互联网冲浪,不然你现在碰着的风趣站点全是动态的。当代的应用程序大都分层,而且能够通过在层间增添缓存来使那个分层特别平价。ChangingThePresent 在多少库层选用了一部分缓存。接下来,作者将长远研究分裂等级次序的缓存,还可能会介绍大家为 ChangingThePresent 都使用了何种缓存。
缓存静态内容

在那三种技艺中,小编更欣赏第二种,因为第一和第二种本领都会将 Rails 应用程序牵扯进来。要得到最大限度的可伸缩性,将要硬着头皮多地使用静态内容。在本文中,作者会爱戴于介绍第二种办法。请不要采纳该措施囤积任何无法丢失的机警数据,比如ICBM 运行代码或信用卡号。对于大家所拍卖的那么些轻便的数码来说,这种艺术效果很好。
使用 Show and tell 还是 hide and seek?

Mongrel 是一种 Web 服务器,由 Zed Shaw 利用 2500 行 Ruby 和 C 编写而成。那么些小型的服务器占用内部存款和储蓄器极少,特别适合 Ruby Web 应用程序,譬如Rails、Nitro、Iowa 等等。Mongrel 可运转于 UNIX? 和 Linux? 上,也可运转在 Win32 上。Mongrel 也时常能够作为代理运维在另贰个 Web 服务器(举例 Apache 或 Litespeed)的后端,但那不是必需的 —— 因为 Mongrel 是一种 HTTP 服务器,能够与富有你偏好的 HTTP 工具结合使用。

在本身刚开首先考试着缓存这么些主页时,笔者本得以归纳地用 JavaScript 替换那么些链接。能够将这种技能看成是 Show-and-tell。基于大家对已登陆用户的刺探,能够使用 JavaScript 采取性地更迭或注入 Web 页的某个剧情,从而为用户提供不错的体会。为了尤其划分,笔者会进行如下操作:

除此而外图像之外,有关缓存静态数据的始末,可讲的内容没有多少。由于大家的网址是一个慈祥性质的门户网址,那表示我们供给越来越多地关心用户的感想,比如多进入一些图像或录制。但我们的 Web 服务器 Mongrel 并不能够很好地服务静态数据,因而大家选取 Apache 来服务图像内容。

  •     创建只具有全数用户的公物成分的 Web 页。
  •     当用户登陆时,将一些有关该用户的多少存入 cookie,比方说登陆信息。
  •     然后,使用 JavaScript 依赖 cookie 的内容注入 HTML 段,借此填充该页面包车型大巴剩下部分。

笔者们以后正在初阶转向使用图形加快器 Panther Express 来缓存最日常被利用的图像以使其能够越来越快地被大家的客户走访到。要运用这种政策,大家将索要多个子域 images.changingThePresent.org。Panther Express 直接在图像的地头缓存中提供图像服务,然后再向大家发送央求。由于 Panther 服务并不知道咱们曾几何时会变动图像,所以大家应用 HTTP 报头来使其到期失效,如下所示:
HTTP 缓存失效报头

对于 ChangingThePresent 主页来说,show-and-tell 技术有些威力过度,因为自个儿唯有两套链接要依靠所登入的用户加以显示。因而,我选用了第三种手艺,作者叫作 hide-and-seek。首先,展现出富有用户的集体页面成分,并因而各种数据恐怕的潜伏版本显得页面包车型大巴变动部分。那正是 hide 部分。然后,依据用户的剧中人物使用 JavaScript 在文件中找到该用户的源委并出示出来。那正是 seek 部分。您或然会想,展现全数希望数量的本子有一些威力过度,实际上,选用性地为差别的海东角色启用二种特色时,这种措施是那多少个大范围的。hide-and-seek 情势非常适合 ChangingThePresent 主页。要落实这种方式,能够实践如下操作:

HTTP/1.1 200 OK
Cache-Control: max-age=86400, must-revalidate
Expires: Tues, 17 Apr 2007 11:43:51 GMT
Last-Modified: Mon, 16 Apr 2007 11:43:51 GMT
  •     创造只具备全数用户的共用成分的 Web 页。
  •     将用户按类型分区。为各类用户类型丰盛内容版本。就自己的具体情形来讲,ChangingThePresent 主页的用户类型包罗登陆用户和刊登用户。最初,让此内容可知。
  •     当用户登入时,将一些可分别用户分组的数据存入 cookie,举个例子说用户剧中人物或登陆状态。
  •     当用户访问此页时,采用性地展示用户类型的开始和结果版本。

留神那一个不是 HTML 报头。它们与 Web 页面内容独立创设。Web 服务器将承受创设那个 HTTP 报头。像那样一篇关于 Rails 的小说连串若详细介绍 Web 服务器配置,未免有个别偏题,所以自身将直接切入可用 Rails 框架实行调控的缓存内容这一核心(有关 Web 服务器配置的更加多内容,请参见 参谋资料 中的相关链接)。
页面缓存

实现 hide and seek

只要动态页面有难题转移,能够应用页面级的缓存。举个例子,Blog 和文告牌使用的正是这种缓存。通过页面缓存,Rails 就足以用来营造动态 HTML 页,并将此页存款和储蓄在公共目录,那样,应用程序服务器就足以像服务其余静态页面同样来服务那些动态页。

对于 ChangingThePresent 主页来说,hide-and-seek 达成起来特别简单。在在此以前的图 第11中学,此主页有贰个有个别显得的是与用户帐户相关的一些链接。那几个链接能够依照用户是或不是登入而变化。首要职业是营造此页的富有国有内容。作者在本文并未提交具体做法。第二页供给出示出装有用户的总体动态内容,而随意用户是或不是已经报到:
清单 1. 在单纯视图中制造动态内容的保有版本

比方页面已经被缓存,那么就不供给引进 Rails,页面缓存是 Rails 内速度最快的一种缓存。在最尾部,页面缓存实际上在 Rails 中国和北美洲常轻巧完成。页面和分支缓存二者均在调节器等第发生。您供给告诉 Rails 如下内容:

<div id='logged_out'>
 <%= link_to "login", :controller => 'members', :action => 'login' %>
 <br />
 <%= link_to "register", :controller => 'members', :action => 'signup' %>
</div>
<div id='logged_in' style="display: none;">
 <%= link_to "your profile", :controller => 'profiles', :action => 'show' %>
 <%= link_to "logout" , :controller => "members", :action => "logout" %>
</div>
  •     想要缓存哪些页面?
  •     当页面内容更改时,您什么能在缓存中让该页面到期失效?

您或者曾经注意到 my profile 链接。早先,该链接指向用户特定的安顿文件,但诸如此类大概会妨碍我们的主页缓存。相反,笔者只简轻巧单地将此链接指向了无任何用户 ID 的目录操作。然后,索引操作会将用户重定向到科学的配置文件页:
清单 2. 将用户重定向到科学的布局文件页

能够经过在支配器类中应用 caches_page 指令来启用页面缓存。比如,若要在 about_us_controller 缓存 privacy_policy 和 user_agreement 页面,能够输入如下代码:
清单 2. 启用页面缓存

  def index
    redirect_to my_profile_url
  end
class AboutController < ApplicationController
 caches_page :privacy_policy, :user_agreement 
end

在清单 2,my_profile_url 是叁个措施,该办法可以依附用户的种类(这或者是有名的人、顾问或会员)决定准确的布置文件 U宝马X3L。各种用户类型都有八个独门的陈设文件页。那时,程序的效果已经完结,您一齐能够见见两个链接,logged_in 和 logged_out 各有八个链接:

让页面到期失效则能够通过 expire_page 指令来促成。若要在 Rails 调用 new_pages 动作时使上述页面到期失效,能够行使如下代码:
清单 3. 使页面失效

  •     login
  •     register
  •     your profile
  •     logout
class AboutController < ApplicationController
 caches_page :privacy_policy, :user_agreement 

 def new_pages
  expire_page :action => :privacy_policy
  expire_page :action => :user_agreement
 end

end

下一步,获取含有当前用户类型的 cookie。对于 ChangingThePresent,小编在登入时创设了贰个 cookie,个中累积当前的报到 ID。之后,在登出时再销毁那几个 cookie:
清单 3. 在报到和发布时创制和销毁 cookies

别的,有多少个小标题亟需专注,譬如 U猎豹CS6L。U奥迪Q5L 不能够依附于 U福睿斯L 参数。譬喻,应该使用 gifts/water/1 而非 gifts/water?page=1。在 routes.rb 中应用那类 U中华VL 将特别轻便。比方,大家的页面中总是有一个选项卡参数用来体现哪个选项卡被当下相中。若要将此选项卡作为 UENCOREL 的一部分,大家会有如下的路由法则:
清单 4. 选项卡的路由法则

def login
 if request.post?
  self.current_user = User.authenticate(params['user_login'], params['user_password'])
  ...

  if logged_in?
   set_cookies
   ...
  end
end

def logout
end

private

def set_cookies
 cookies[:login] = current_user.login
 cookies[:image] = find_thumb(current_user.member_image)
end

def logout
 cookies.delete :login
 cookies.delete :image
 ...

end

复制代码 代码如下:

在清单 3 中,logged_in? 是二个个体方法,如若当前用户已登陆则赶回 true。上述的 Rails 方法会在你登入时成立多个cookie,并在登出时去除它们。这里无需为多少费神。尚且不需用到数码。能够如此敞亮:无需调用 Rails 框架,笔者就可以判明用户是或不是登入。小编不用确定保障 cookie 到期结束是或不是与站点的到期甘休规定符合。在本身的例证中,二者是相符的,所以笔者明天尽可以开头页面缓存了。

map.connect 'member/:id/:tab', :controller => 'profiles', :action => 'show'

下一步,依据用户的 cookie 采用性地隐藏和呈现精确的条文。将如下的 JavaScript 代码增加到 public/javascripts/application.js 中:
清单 4. 支持 show and hide 登录 div 的 JavaScript 代码

对于持有页面参数的那三个列表以及凭仗于 UCRUISERL 参数的其余页面,也亟需动用一样的做法。别的,还亟需思索安全性难题。

function readCookie(name) {
  var nameEQ = name   "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i  ) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  }
  return null;
}

function handle_cached_user() {
 var login_cookie = readCookie('login');
  var logged_in = document.getElementById('logged_in');
  var logged_out = document.getElementById('logged_out');
  if(login_cookie == null) {
   logged_in.style.display = 'none';
   logged_out.style.display = 'block';
  } else {
   logged_out.style.display = 'none';
   logged_in.style.display = 'block';
  }
}

举个例子页面已经在缓存内,那么就不会用到 Rails 框架,服务器并不可能为你管理安全性。Web 服务器将更乐于在缓存内呈现任何页面,而随意用户是否对其兼具查看的权位。所以,假如您很关切页面可由哪个人查看,那么就无须采纳页面缓存。

首先个函数从 Javascript 中读取 cookie 值,第三个函数管理此 DOM。能够透过利用 Prototype 库简化这段代码,但自身回顾了主导的 DOM 查找以便于读者精通。最终一步是在页面加载时调用 JavaScript 函数。小编向布局中加多了之类代码:
清单 5. 当页面加载时调用 JavaScript 函数

如果只是想缓存简单的静态页面,那么精通上述剧情就应该足够了。只要内容简短,实现起来就轻便。

  <script type="text/javascript">
   window.onload = function() {
     handle_cached_user();

     <%= render_nifty_corners_javascript %>
      <%= yield :javascript_window_onload %>
   }
  </script>

当想要缓存更为复杂的内容时,就须要实行部分衡量取舍了。由于想要缓存的页面高度动态,所以到期失效逻辑就能变得更为复杂。要管理目眩神摇的到期失效逻辑,将索要编写制定和配备定制清理器(sweeper)。在一些调控器击发时,那几个类会从缓存内去除选定的因素。

上述 JavaScript 代码十一分简约。在页面加载时,将加载 handle_cached_user 函数,而它会相应地显示或隐藏正确的原委。将来,小编尽能够由此向调整器中增加如下代码来启用页面缓存:

大大多定制清理器都会观察某个模型对象,并依据退换击发逻辑来使二个或四个缓存页面到期失效。清单 5 显示了一种标准的缓存清理器。在此清理器中,开荒人士能够定义三个移动记录事件,比方after_save。当此事件击发时,清理器也会击发,并可让缓存内的一定页面到期失效。这一个事例所突显的到期失效基于 expire_page 方法。而广大严谨的应用程序大都直接动用 Ruby 卓越的文件系统实用工具来显式地删除所缓存的页面。
清单 5. 多个特出的观察器

  caches_page :index
class CauseController < ApplicationController
  cache_sweeper :cause_sweeper
...

class CauseSweeper < ActionController::Caching::Sweeper
 observe Cause

 def after_save(record)
  expire_page(:controller => 'causes', :action => 'show', 
        :id => record.id)
  cause.nonprofits.each do |nonprofit|
   expire_page(:controller => 'nonprofits', :action => 'show', 
         :id => nonprofit.id)
   end
  end
end

上述代码效果极佳。作者照旧须要按时地从缓存中剔除前页,那样作者技能使该页期满终止。为此,作者只需简单地定时删除 public/index.html。hide-and-seek 方式对于有几类用户的页面十分卓有作用,但对于如图 2 中所示的用户 partial 效果却倒霉。对于后者,要求综合应用 hide-and-seek 和 show-and-tell 技能。
实现 show-and-tell

今昔,您大概会开始感觉到页面缓存的略微缺点了:复杂性。您尽管能够很好地开展页面级的缓存,但原有的纷纷却让应用程序很难测量检验,进而会大增系统内冒出 bug 的恐怕。而且,假如页面针对各类用户都会迥然分歧,也许希望缓存举行过身份验证的页面,那么将需求使用页面缓存之外的秘籍。对于 ChangingThePresent,大家亟须处理二种境况,原因是大家必须依据用户是不是登入来改变基本布局上的链接。对于大多数页面,大家以致都不会思索采纳页面级缓存。为了让您可以深切摸底页面级的缓存,在本文的 参照他事他说加以侦查资料 部分,小编极度给出了到一多级关于页面级缓存的绝妙小说的链接。接下来,以后深切钻探另一种样式的整页缓存 —— 动作缓存。
动作缓存

再来看看 图 2。俺将应用 hide-and-seek — 依据用户是或不是已报到 — 选用partial 的科学版本,然后选拔 show-and-tell 技能根据作者前面在清单 3 的行 4 和行 5 中所写的 cookies 的故事情节填充页面包车型地铁动态部分。请牢记,对于 show-and-tell,小编特地改换了页面包车型大巴因素以契合单个用户的情形。

从那之后,您曾经精通了页面缓存的第一的优势及主要性的顽固的疾病:对于绝大许多页面检索来说,根本无需思虑使用 Rails。页面缓存的优势是速度快。缺点是缺点和失误灵活性。假如想要基于应用程序内的规格 — 比如,身份ID明 — 来缓存整个页面,那么可以运用动作缓存。

首先,实现在那四个 partial (即登出用户和登陆用户)上显现的静态内容。笔者一旦用户已经登出,所以作者会通过附加 display: none 风格隐藏 logged_in div。之后,假如须要,笔者就足以用 JavaScript 展现或隐蔽它们。请留意,作者动用了扳平的两个称呼:logged_in 和 logged_out,来识别每一个 div,那样便不必对本人为这几个主页所编写的 JavaScript 进行修改:
清单 6. 表现登陆和刊登那多少个 partial

动作缓存与页面缓存的干活措施大约一样,但在流水生产线上稍有反差。Rails 在表现动作前会实际调用调节器。假设由该动作表现的页面已经存在于缓存内,那么 Rails 就能够在缓存内显示页面而不是重复加以彰显。由于昨日采取了 Rails,因而动作缓存的进程要比页面缓存慢一些,但其优点照旧很显眼的。差不离全数的 Rails 认证形式都会在调整器上使用 before 过滤器。动作缓存令你能够利用认证及调控器上的别样过滤器。

<div class="boxRight sideColumnColor">
  <div id='logged_in'>
    <%= render :partial => 'common/logged_in' style="display: none; %>
  </div>
  <div id='logged_out'>
    <%= render :partial => 'common/logged_out' %>
  </div>
</div>

从语句构成的角度来看,动作缓存与页面缓存也应有充足近乎,唯有指令不太同样。清单 6 呈现了何等利用 caches_action 指令。
清单 6. 启用动作缓存

接下来,完成 logged_in partial 的剧情。注意,每一种包涵动态内容的 HTML 组件都有贰个 ID,从而作者能够使用 JavaScript 找到它并随就要其替换:
清单 7. 显示 logged_in partial

  class AboutController < ApplicationController
   caches_action :secret_page, :secret_list 
  end
<div id='logged_in' style="display: none;">

 <%= link_to %(Hi, )  
    %(<b id='bold_link'>)   "my_login"  
    %(</b>), {:controller => 'profiles', :action => 'show', :id => 'my_login'},
 {:id => 'profile_link'} %>
 <br/>

 <div id='picture_and_link'>
   <a href="http://member/my_login" id='link_for_member_thumbnail'>
     <img id='member_thumbnail'
        alt="Def_member_thumbnail"
        src="/images/default/def_member_thumbnail.gif" /></a>
 </div>

 <div id="not_mine">Not my_login?</div>
 <br/>
 <%= image_button "logout", :controller => "members", :action => "logout" %>

缓存到期失效以及清理器的干活措施也相应同等。大家不接纳动作缓存的原故与我们不应用页面缓存的原由是一模一样的,但分段缓存对我们来讲更主要片段。
缓存页面分段

如若对 Rails 有丰硕的掌握,您恐怕会小心到在那之中的多少个定制支持程序函数。从中可以见见四处很明朗的动态内容,作者索要利用 JavaScript 为每一种加载的页面替换那个内容:三处登陆,一处会员图像。此处的 JavaScript 代码对 handle_cached_user 函数作了一处修改,并且还带有三个为动态用户管理页面更新的法子。针对本文的具体情状,小编多少对这段代码做了一定量简化。能够将如下函数增加到 application.js 文件中:
清单 8. 替换用户 partial 的因素

重视部分缓存,能够缓存页面包车型地铁一有的,所缓存的剧情好多时候皆以布局之类的。要接纳分段缓存,开辟人士须要先分明分段,方法是透过在 Web 页面上间接放上 rhtml 指令来包围一块内容,如清单 7 所示。在 ChangingThePresent.org 上,大家利用分段缓存来缓存首页和其它的几页。全体的这个页均使用了数据库密集访问而且多数是咱们最受接待的页面。
清单 7. 规定缓存分段

function handle_user_partial() {
 var login_cookie = readCookie('login');
 var image_cookie = readCookie('image');

  var profileLink = document.getElementById('profile_link');
  profileLink.href = '/member/'   login_cookie;

  document.getElementById('bold_link').firstChild.nodeValue=login_cookie;

  document.getElementById('not_mine').firstChild.nodeValue="Not "   login_cookie   "?";

  document.getElementById('link_for_member_thumbnail').href="/member/"   login_cookie;

  document.getElementById('member_thumbnail').src=image_cookie.replace(/%2[Ff]/g,"/");

  document.getElementById('member_thumbnail').alt=login_cookie;

}
<% cache 'gifts_index' do %>
  <h3>
   Here, you can make the world a better place with a single gift. Donation gifts 
   are also a wonderful way to honor friends and family. Just imagine what we
   can achieve together.
  </h3>
  <h2 class="lightBlue"><%= @event_title %></h2>
  <div id="homefeatureitems">
    <% for gift in @event_gifts %>
     <%= render :partial => 'gifts/listable', :locals => { :gift => gift } %>
    <% end %>
  </div>
  ...
<% end %>

在清单 8 中,这些 JavaScript 函数首先读取此 cookies 并得到 DOM 树的一局地:即到当下的用户配置文件的链接,称为 profile_link。然后是 handle_user_partial 函数:

在清单 7 中,cache 扶助程序标记所要缓存的分区。第3个参数是标记此缓存分区的惟一名称。第贰个参数包含代码块 — 即首先个 do 和最后多个 end 之间的代码 — 此代码块精确地规定了要缓存的 汉兰达HTML 分区。

  •     将登陆用户的名号(存款和储蓄在 login_cookie 内)替换成 my_login 感到用户配置文件页成立准确的 URubiconL。
  •     将登陆用户名插入到 DOM 成分中,此成分使用粗体文本表示登陆用户。
  •     将简单的句子 “Not login?” 插入到 DOM 成分中,这些成分包蕴 login partial 中的 logout 标题。
  •     找到包蕴会员图像的 dom 成分,将一般图像的 URubiconL 替换到会员图像的 U途胜L,会员图像保存在 image_cookie 中。
  •     别的,还要将此图像的 alt 标志替换来 login 名称,避防图像不出现。

大家的网址唯有三个主页,所以命名那些页面特别轻易。在别的地方,大家运用一种特定的点子来调整此网页的 U奥德赛L 以便惟一标志缓存分段。举例,当大家为一定的故事情节(比方世界和平或回降贫穷)而开展代码缓存时,大家须求运用清单 8 中的代码。代码会为之搜索永远 url,也叫做 permalink。
清单 8. 因此 U中华VL 标志缓存分段

在 DOM 中程导弹航时,会发觉有时需求向来转到 DOM 成分,而有时又供给转到该因素的特定子元素,举个例子在拍卖文件的时候。笔者就选用了 firstChild 函数依照要求搜索 DOM 成分的率先个子成分。由于语法更为和谐,所以 Prototype 库使拍卖特定的 DOM 成分较为轻松一些,但那超出了本文的探究范围。

<% cache @cause.permalink(params[:id]) do %>

自家曾经创办好了颇具的 cookies,最终一步就是从 handle_cached_user 函数调用 JavaScript。请记住,该函数在 public/javascripts/application.js中:
清单 9. 将 handle_user_partial 函数增多到 handle_cached_user

常见,当缓存单独页面时,必要用清理器使之过期失效。有的时候,使用轻易的依靠时间的指标过期更为轻便和轻巧。暗中认可地,Rails 并不提供这类机制,但有一种插件名叫 timed_fragment_cache 能够达成这一目标。借助那些插件,作者得以钦命超时,可以在缓存了的内容中钦定,也得以在为此页提供了动态数据的调控器代码中钦点。比方,清单 9 所示的代码就足认为此页面营造动态数据。when_fragment_expired 方法唯有在连带的缓存分段过期时才会推行。此情势接受参数,用来钦点超时的时间长度,它还接受二个代码块,用来钦定当内容过期时怎么样内容必要重建。我也能够选用在 rhtml 页面中钦点超时和缓存方法,但自个儿更愿意利用基于控制器的章程。
清单 9. 基于时间的缓存到期

function handle_cached_user() {
 var login_cookie = readCookie('login');
  var logged_in = document.getElementById('logged_in');
  var logged_out = document.getElementById('logged_out');
  if(login_cookie == null) {
   logged_in.style.display = 'none';
   logged_out.style.display = 'block';
  } else {
  handle_user_partial();
   logged_out.style.display = 'none';
   logged_in.style.display = 'block';
  }
}
def index
 when_fragment_expired 'causes_list', 15.minutes.from_now do 
  @causes = Cause.find_all_ordered
 end
end

请小心,else 条件中的 handle_cached_user 函数上边还应该有额外两行代码。这两行代码能够在使 logged_in DOM 成分可知从前举行适当的代表。剩下所需做的正是接纳本篇文章和 下三个月的这篇小说中所介绍的页面缓存指令来缓存整个页。
结束语

借使可以容忍数据稍微有一些陈旧,那么使用定期的到期机制将得以大幅度地简化缓存战术。对于每种被缓存的要素,只需点名想要缓存的源委、可生成动态内容的任何调节器动作以及超时。与页面缓存类似,若是急需,也得以行使 expire_fragment :controller => controller, :action => action, :id => id 方法显式让内容到期。此方式的做事方法与缓存动作和缓存页面包车型客车到期失效是千篇一律的。接下来,笔者将介绍怎样陈设此后端。
Memcached

本篇文章中介绍的这种高端技巧为大家开垦了许多方便之门。在 ChangingThePresent.org 上,大家估摸应用极度轻松的依据时间的清除器能够缓存超越 33.33%的页面。通过接纳稍微有些复杂的铲除技艺,大家就能够缓存超越 百分之八十的页面,而且还可能越多。要是你想计较影响我们的图像缓存安排,那么您不得不触及应用服务器 1% 到 3% 的 Web 央求。

至此甘休,小编一度介绍了 Ruby on Rails 的页面和分层缓存模型。看过了 API 之后,未来就足以定义缓存后的多寡的去处了。暗许地,Rails 将把缓存后的页面放入文件系统。缓存后的页面和动作都会跻身国有目录。能够配备缓存后的分层的贮存地方。为此,须要利用内部存款和储蓄器存储、文件系统(在所定义的目录)、数据库或称为 memcached 的劳动。对于 ChangingThePresent.org,我们选取 memcached。

但同期,我们也应当看到不利的一边。小编向此系统增添了斐然的纷纭。作者必须爱抚越发复杂的 HTML 代码,并保管 HTML 和 JavaScript 能够维持同步。但好的一面是在急需得到更加好的习性时,小编就能够运用最为轻松和有效性的缓存技艺。您也得以尝尝选用这种才干— 访问 ChangingThePresent.org 并加载主页。接下来,加载各种上边的美食指南。您会发觉大家会页面缓存两个最上部菜单中的多个。创制八个帐号同样重视载每叁个菜系。您能猜到哪个页面被缓存了么?在下一篇文章中,在持续深入实际世界中的 Rails 的还要,作者将带你研商能提升 ActiveRecord 品质的局地技巧。

能够将 Memcached 想象为二个特大型的 hash 图,那几个图可通过互连网获得。基于内部存款和储蓄器的缓存速度快,而依附网络的缓存的可伸缩性相比较好。有了插件帮忙,Rails 就可利用 memcached 来缓存分段和 ActiveRecord 模型。要运用它,须求设置 memcached(越来越多音信,请参看 参谋资料)并在 environment.rb(或别的的条件布署文件,比方production.rb)对它进行布署。
清单 10. 配置缓存

您恐怕感兴趣的稿子:

  • ruby on rails 代码技艺
  • 在Ali云 (aliyun) 服务器上搭建Ruby On Rails情状
  • Windows下Ruby on Rails开拓条件设置配置图像和文字化教育程
  • win7安装ruby on rails开拓遭逢
  • 在Docker中自动化安顿Ruby on Rails的课程
  • 详解Ruby on Rails中的Cucumber使用
  • 对优化Ruby on Rails品质的片段办法的钻探
  • Ruby on Rails基础之新建项目
config.action_controller.perform_caching = true

memcache_options = {
 :c_threshold => 10_000,
 :compression => false,
 :debug => false,
 :readonly => false,
 :urlencode => false,
 :ttl => 300,
 :namespace => 'igprod',
 :disabled => false
}

CACHE = MemCache.new memcache_options

清单 10 突显了一种规范的陈设,当中第一行 config.action_controller.perform_caching = true 将启用缓存。接下来的一行将盘算缓存选项。注意,这里的居多挑选是为了让您能够得到更加多的调节和测量检验数据、禁止使用缓存和定义该缓存的称号空间。在 参谋资料 部分交给的 memcached 站点能够找到关于安顿选项的更加的多音讯。
模型缓存

作者们运用的结尾一种缓存是基于模型的缓存。大家选取的是称呼 CachedModel 的缓存插件的一种定制版本。模型缓存实际上是一种简单格局的数据库缓存。缓存很轻巧按模型启用。

要想让模型使用缓存解决方案,只需扩充 CachedModel 类,而非扩大ActiveRecord,如清单 11 所示。 CachedModel 扩充ActiveRecord::Base。ActiveRecord 并非全对象关系型映射层。此框架十分的大地借助于 SQL 来施行复杂的特点,而且假使急需,用户能够很轻巧降至 SQL。间接行使 SQL 会使缓存出难题,因为缓存层必须管理一体化的结果集,而不是独立多少个数量库行。管理一体化的结果集日常会难题不断,而且只要未有帮助应用程序的深层逻辑,那差十分的少不太可能。正由于那几个原因,CachedModel 的关节才会停放慢存单个模型对象上,并只加快重回单行结果的查询。
清单 11. 使用 CachedModel

Class Cause < CachedModel

大好些个 Rails 应用程序都会再次访问多个条目,比方用户对象。模型缓存在重重情景下都足以显著地使速度加快。对于 ChangingThePresent,大家刚刚起先加快基于模型的缓存。
结束语

Ruby 就算是一门生产率相当高的语言,但若从性质角度考虑,该语言解释性的特征让它并不那么美好。大好些个关键的 Rails 应用程序都将会透过有效应用缓存来弥补一些不足。对于 ChangingThePresent.org,大家根本选取分段缓存,并经过调控器选用基于时间的方法来使缓存分段到期失效。这种格局很适合我们的网址,纵然当中有部分页面会基于登入进来的用户具备转换。

小编们还研究了使用受 memcached 支撑的 CachedModel 类所能带来的熏陶。纵然大家的琢磨还只限于缓存对数据库质量所形成的影响,但开始时代的结果依然很有期望的。在 下一篇 小说中,笔者将介绍一些实用本领,您可以使用那个才能来为另三个不追求虚名世界中的 Rails 示例举办数据库优化。

您恐怕感兴趣的稿子:

  • 在localStorage中蕴藏对象数组并读取的法子
  • 详解JavaScript中localStorage使用要点
  • android webview 中localStorage无效的化解方法
  • JS localStorage完毕地点缓存的措施
  • 使用jquery读取html5 localstorage的值的格局
  • Android使用缓存机制落到实处公文下载及异步诉求图片加三级缓存
  • PHP缓存机制Output Control详解
  • jQuery的缓存机制浅析
  • 回顾的php缓存类分享php缓存机制
  • 一抬手一动脚端应用localStorage缓存Js和css文的方法(web开拓)
  • localStorage的黑科学和技术-js和css缓存机制

本文由必发88手机版发布,转载请注明来源:Rails中的缓存机制,多少个加速Ruby