`
mypages
  • 浏览: 87907 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

rails 生成静态页面

阅读更多
rails 生成静态页面
2008-06-11 09:13
当你网站访问量上升的时候,你可能为你的rails项目增加一些缓存应用。这个教程将告诉你关于rails缓存的方方面面,帮助你提高rails应用,而不必再为过度的cpu开销而烦心。

rails缓存有几种方式,这篇教程将分几个部分向你分别介绍如何应用不同的缓存方案,以及一些高级的有针对性的缓存应用。

首先介绍最快速的缓存应用:Page Caching,页面缓存

1、为什么要进行缓存
(如果你已经对缓存的必要性有所了解,可以跳过本段)
ruby是一种解释性语言,这意味着ruby代码在没有被执行前,是不会编译成机器能识别的机器码的。
这个特点和php是一样的,但是java在这方面完全不同(java是先编译成机器码,后运行的)。
所以,当有人访问你的ruby程序的时候,你的代码才被读取并执行,你可以想象一下,当每秒钟有100个人访问你的代码的时候,你的程序将会消耗掉很多的系统资源。
那么改如何解决呢?
(译者:本篇文章讨论的是Rails框架中的缓存机制,Ruby是开发Rails框架的一种语言,和java,c语言一样的。)


2、缓存
缓存是web处理(web应用)中的一个重要的设计策略,它被放置在一个临时的位置。如果有人请求了一个同样的应用,我们就可以为他提供一个应用的缓存版本。
提供一个缓存,不仅可以使我们的应用不用读取任何数据库资源,而且请求可以不必经过我们的rails应用服务。(译者:这句话很有意思,往后面看吧)
在开始缓存设计之前,有一些rails配置需要设定

3、缓存配置
在开始缓存应用前,你需要配置你的/config/environments/development.rb文件
onfig.action_controller.perform_caching = true
默认情况下,缓存在产品模式下会被启动,上面的设置将在开发环境下启动缓存。

4、Page Caching,页面缓存
页面缓存是最快速的一种缓存应用。那么应该在什么时候使用他呢?
1、对于所有用户都相同的页面
2、公开的页面,没有用户认证的页面
如果你的应用中有符合上述条件的,请继续阅读下面的部分。如果你的应用中没有,那么也请继续阅读,下面的内容更精彩(ps:我觉得全世界的广告都一样,不过郁闷的是deyeb目前没有一个页面符合上面的条件,除了404和500吧)

假设我们正在设计一个blog系统,页面并不经常变化,那么我们的controller可能这样来写:

class BlogController < ApplicationController
  def list
     Post.find(:all, :order => "created_on desc", :limit => 10)
  end
    ...
可以看到,List这个action是查询最近的10篇blog文章,对应的web页面上将会显示查询的结果。
如果我们要对这个页面进行缓存的话,只需;

class BlogController < ApplicationController
   caches_page :list  
   def list
     Post.find(:all, :order => "created_on desc", :limit => 10)
   end
    ...
”caches_page“将会在下次请求list这个action时,将页面内容存入一个html页面,放置在一个缓存目录里。

当你在mongrel里第一次运行该代码,访问这个页面的时候,你会在
/logs/development.log log日志中发现下面的代码:
Processing BlogController#list (for 127.0.0.1 at 2007-02-23 00:58:56) [GET]
 Parameters: {"action"=>"list", "controller"=>"blog"}
SELECT * FROM posts ORDER BY created_on LIMIT 10
Rendering blog/list
Cached page: /blog/list.html (0.00000)
Completed in 0.18700 (5 reqs/sec) | Rendering: 0.10900 (58%) | DB: 0.00000 (0%) | 200 OK [http://localhost/blog/list]
注意这一句:Cached page: /blog/list.htm,
这说明,这个页面已经被加载,而且最终你看到的html页面已经被储存在 /public/blog/list.htm 这个位置,如果你检查一下这个页面的话,你会发现上面没有一行ruby代码。

以后,如果当有访问同样的url地址的时候,加载的将是这个html页面,而不适重新加载这个controller中的action(译者:这样说更清楚)。想像的到,加载一个静态的页面可是比加载并处理一个解释性语言要快得多,几乎快上100倍!(ps:这是真对大访问量情况下的有效的解决办法,同时也是普通网站的一个很好的设计架构。)

但是只得注意或提醒的是,这样一个静态页面是没有执行任何ruby代码的。所以,当你的页面需要反应一些及时的用户信息,或者当前的信息,你就不能采用这种页面缓存,而是采用局部缓存。这个将在第二部分有讲解。

回到我们的model,
caches_page :show
你猜,当我们访问某一篇具体的文章,比如"/blog/show/5“时,这个页面会被缓存在哪里?
答案是 这里:
/public/blog/show/5.html
下面的例子说明页面缓存的位置
http://localhost:3000/blog/list => /public/blog/list.html
http://localhost:3000/blog/edit/5 => /public/edit/5.html
http://localhost:3000/blog => /public/blog.html
http://localhost:3000/ => /public/index.html
http://localhost:3000/blog/list?page=2 => /public/blog/list.html
注意:第一行和最后一行的缓存文件是同一个,页面缓存是忽略掉url地址上的参数的。


5、如何缓存我的分页
为了缓存不同的页面,你需要不同的地址。(译者:我疯了,这个问题没想到,继续看吧)因为页面缓存的时候会忽略掉像
/blog/list?page=2这样的参数,所以你需要使用/blog/list/2这样的地址形式,而原来我们使用的是id保存参数值,现在我们需要用page来保存参数值。
下面我们修改 /config/routes.rb文件
map.connect 'blog/list/:page',
    :controller => 'blog',
    :action => 'list',
    :requirements => { :page => /\d+/},
    :page => nil
使用了新的routes定义,我们的连接也应该改成
<%= link_to "Next Page", :controller => 'blog', :action => 'list', :page => 2 %>
最终的连接结果是"/blog/list/2",当我们点这个连接的时候,后台会处理两件事情
1、应用将2放入page这个参数中,而不是原来id这个参数
2、缓存将生成 /public/blog/list/2.html 这个页面

所以,缓存分页,就要将页面参数变成页面的一部分,而不要使用地址参数的形式,他是会被忽略的。

6、清除缓存
看完上面的内容后你可能想问,如果我添加完一篇新的文章到博客,该如何刷新
/blog/list这个action呢?
来,看一下我们几分钟前创建的
/blog/list.html 页面,它并不包含我们新创建的那个新文章。为了删除这个缓存,并生成一个新的缓存,我们需要让这个页面过期。为了是上面的两个页面过期,我们需要做:
# This will remove /blog/list.html
expire_page(:controller => 'blog', :action => 'list')

# This will remove /blog/show/5.html
expire_page(:controller => 'blog', :action => 'show', :id => 5)
显然我们需要在每一个执行了添加,删除,修改的地方粘贴上面的代码,但是还有一个更好的方法来解决问题。
(译者:头一次翻译这么长的文章,上面写的大家能看明白吗?百度空间发表的这篇文章是首发,完成后会在几个地方转载,大家多提意见)

7、Sweepers,缓存自动清理
sweepers是一段自动删除旧的缓存的代码。为了实现这个功能,sweepers需要跟踪你的models,当你的model执行了增删改后,sweepers就会执行上面的命令。
sweepers可以在你的controllers目录创建,但是我觉得他应该隔离开。你可以在
/config/environment.rb.进行个设置:
Rails::Initializer.run do |config|
   # ...
     config.load_paths += %W( #{RAILS_ROOT}/app/sweepers )
   # ...
end
ps:记得重启你的服务
这样,你就可以在/app/sweepers 这个目录创建你的sweepers了。/app/sweepers/blog_sweeper.rb
的代码可以这样来写:
class BlogSweeper < ActionController::Caching::Sweeper
    observe Post # This sweeper is going to keep an eye on the Post model

  # If our sweeper detects that a Post was created call this
  def after_create(post)
            expire_cache_for(post)
  end
  
  # If our sweeper detects that a Post was updated call this
  def after_update(post)
            expire_cache_for(post)
  end
  
  # If our sweeper detects that a Post was deleted call this
  def after_destroy(post)
            expire_cache_for(post)
  end
          
    private
  def expire_cache_for(record)
    # Expire the list page now that we posted a new blog entry
      expire_page(:controller => 'blog', :action => 'list')
    
    # Also expire the show page, incase we just edited a blog entry
      expire_page(:controller => 'blog', :action => 'show', :id => record.id)
  end
end
提示:我们可以使用“after_save”替代“after_create”和“after_update”,你自己来试一下吧!
我们还需要告诉我们的controller什么时候调用了sweepers,所以在controller中需要加入:
class BlogController < ApplicationController
     caches_page :list, :show
   cache_sweeper :blog_sweeper, :only => [:create, :update, :destroy]
     ...
好了。我们可以尝试着添加一个新文章,这样在logs/development.log:中你会发现
Expired page: /blog/list.html (0.00000)
Expired page: /blog/show/3.html (0.00000)
我们的sweepers已经工作了!
(译者:这是本文的第一个重要知识)


8、rails缓存与Apache/lighttpd的配合应用(deyeb关注的事情)
当我们将rails应用部署到产品环境的时候,我们多数采用的是apache服务器作为rails服务的前端,将rails请求转发到rails服务器上(
Mongrel 或 Lighttpd)。因为我们使用了缓存静态文件的方法,所以我们需要告诉apache服务器,服务请求的是否存在静态页面缓存,如果有,则直接读取静态文件,而不用请求rails服务器了。(deyeb的设计如果这么简单就好啦)
httpd.conf的配置
<VirtualHost *:80>
    ...
  # Configure mongrel_cluster
    <Proxy balancer://blog_cluster>
    BalancerMember http://127.0.0.1:8030
    </Proxy>

    RewriteEngine On
    # Rewrite index to check for static
    RewriteRule ^/$ /index.html [QSA]

  # Rewrite to check for Rails cached page
  RewriteRule ^([^.]+)$ $1.html [QSA]

  # Redirect all non-static requests to cluster
  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
  RewriteRule ^/(.*)$ balancer://blog_cluster%{REQUEST_URI} [P,QSA,L]
    ...
</VirtualHost>
lighttpd 的配置写法
server.modules = ( "mod_rewrite", ... )
url.rewrite += ( "^/$" => "/index.html" )
url.rewrite += ( "^([^.]+)$" => "$1.html" )
代理服务器将会查看你放置在 /public 目录下的静态文件,但是你可能想将这个缓存位置改变一下,以保持独立性。那就继续看下面的介绍。


9、更改你的缓存放置位置
首先需要在你的
/config/environment.rb 中添加下面的代码
config.action_controller.page_cache_directory = RAILS_ROOT + "/public/cache/"
这是告诉rails服务你需要将缓存文件放置在/public/cache这个目录下,你还需要重写一下httpd.conf规则。
  # Rewrite index to check for static
  RewriteRule ^/$ cache/index.html [QSA]

  # Rewrite to check for Rails cached page
  RewriteRule ^([^.]+)$ cache/$1.html [QSA]
分享到:
评论
1 楼 hz_qiuyuanxin 2013-04-23  
请问,如果 Rails 进程挂了,那么再访问这些静态内容的时候,能不呢个你访问到呢?

相关推荐

    Ruby-HighVoltage容易在Rails应用程序中包含静态页面

    High Voltage - 容易在Rails应用程序中包含静态页面

    Burger2Go-js:完整的JS DOM为公司目标网页生成的静态页面,使用JavaScript ES6,Webpack构建

    分叉或克隆此存储库运行&gt; npm install 运行&gt; npm运行构建浏览器中的opne ./dist/index.html特征静态生成的网页屏幕截图家 接触 菜单建于用Ruby on Rails构建的项目CSS3 ES6 使用的其他软件包引导程序v4.0接触...

    Ruby on Rails Web开发之旅.pdf【第二部分】

     5.3.2 创建静态页面  5.3.3 创建动态页面  5.3.4 反复传递数据  5.3.5 引入模型  5.4 小结 第6章 助手、窗体和布局  6.1 可信任助手  6.2 故事提交  6.2.1 创建窗体  6.2.2 保存数据到数据库中 ...

    Ruby on Rails Web开发之旅.pdf【第一部分】

     5.3.2 创建静态页面  5.3.3 创建动态页面  5.3.4 反复传递数据  5.3.5 引入模型  5.4 小结 第6章 助手、窗体和布局  6.1 可信任助手  6.2 故事提交  6.2.1 创建窗体  6.2.2 保存数据到数据库中 ...

    Ruby on Rails Web开发之旅.pdf【第三部分】

     5.3.2 创建静态页面  5.3.3 创建动态页面  5.3.4 反复传递数据  5.3.5 引入模型  5.4 小结 第6章 助手、窗体和布局  6.1 可信任助手  6.2 故事提交  6.2.1 创建窗体  6.2.2 保存数据到数据库中 ...

    derailer:Rails 应用程序的静态分析工具

    脱轨器Derailer 是 Rails 应用程序的静态分析工具。 它生成一个图表,显示您的应用程序允许数据从数据库流到用户看到的呈现网页的条件。 此图的目标是帮助用户发现可能代表安全漏洞的意外数据流。安装将这些行添加到...

    gakubuchi:使用Asset Pipeline进行静态页面管理

    安装将其放在您的Gemfile中: gem 'gakubuchi' 使用以下命令运行安装生成器: rails g gakubuchi:install 或指定静态页面的目录名称: rails g gakubuchi:install -d html 他们将初始化程序安装到config/...

    吊架:具有我们默认默认值的Rails模板,可以部署到Heroku

    吊带 Suspenders是使用的基本Rails应用程序。 安装 首先安装吊带宝石: gem install suspenders 然后运行: suspenders projectname 这将创建一个Rails应用...静态页面的 的异常通知 以重置浏览器样式 用于访问Pos

    railsapps.github.com:RailsApps网站的内容

    然后,使用位于gem从Wiki生成静态网页。 要提交生成的网页,您需要拥有组织团队成员的存储库读写权限。 目标 这是我设置RailsApp网站时想到的目标: 我想使用GitHub的功能来托管站点。 托管是免费的,并且GitHub...

    BootSaaS:引导您的启动。 一个用于为SaaS应用程序生成基于Bootstrap布局的宝石

    以衡量承诺设置新页面的路线在Heroku上添加Rails 12因子gem以进行资产预编译增加了用于提高安全性的刹车手宝石为您的静态页面添加测试!安装将此行添加到应用程序的Gemfile中(您可能需要修复版本): gem 'bootsaas...

    sustainable-rails.com:网站sustainable-rails.com

    目标-使用React作为模板框架来生成一组静态HTML页面,而不需要JS依赖项。 安装/设置 克隆此仓库 yarn install yarn test (确保一切正常) yarn dev 这将在浏览器中打开样板站点。 它应该指出事物在哪里以及您...

    notes_ruby_on_rails:https

    该网站是使用 (现代的静态网站生成器)构建的。 安装 yarn install 地方发展 yarn run start 此命令将启动本地开发服务器并打开浏览器窗口。 大多数更改都可以实时反映出来,而无需重新启动服务器。 建造 yarn ...

    Assignment-10:带有React的静态网页

    更改页面&lt;title&gt; 安装依赖项 导入组件 代码分割 添加样式表 后处理CSS 添加CSS预处理器(Sass,Less等) 添加图像,字体和文件 使用public文件夹 更改HTML 在模块系统之外添加资产 何时使用public文件夹 ...

    ResourceCenter:静态资源中心

    更改页面&lt;title&gt; 安装依赖项 导入组件 代码分割 添加样式表 后处理CSS 添加CSS预处理器(Sass,Less等) 添加图像,字体和文件 使用public文件夹 更改HTML 在模块系统之外添加资产 何时使用public文件夹 ...

    shinkansen:Grunt HTML网站生成器。 使用JavaScript构建使用JavaScript的网站

    开发人员环境和静态网站生成器 咕unt声 玉 触控笔/笔尖 凉亭 实时重载 现场棉绒 页面速度优化 受Rails启发,新干线就是Omakase。 使用Node JS和Grunt,它将3种模板语言组合在一起。 翡翠-&gt; HTML 触控笔-&gt; CSS ...

    family-tree:演示家庭树生成器thingy使用react和boostrap

    与API后端集成节点Ruby on Rails 在开发中代理API请求配置代理后出现“无效的主机头”错误手动配置代理配置WebSocket代理在开发中使用HTTPS 在服务器上生成动态&lt;meta&gt;标记预渲染为静态HTML文件将数据从服务器...

    Payspec服务器

    一个“显示发票”页面,该页面提供mongo数据库中的发票数据(静态页面,使用元掩码) 具有以下内容的管理员后端(需要控制台生成的密码) 从mongo缓存的所有发票的列表,可搜索 本地API 可以生成和存储预发票并...

    React-App:只有静态

    该项目是通过引导的。... 使用AJAX请求获取数据与API后端集成节点Ruby on Rails 在开发中代理API请求配置代理后出现“无效的主机头”错误手动配置代理配置WebSocket代理在开发中使用HTTPS 在服务器上生成动态&lt;met

    mu-editor.github.io:mu代码编辑器的网站

    它使用GitHub页面功能来构建一个Jekyll(静态站点生成器)项目,该项目将在master的每次提交时发布。 对于本地开发,您可以按照以下说明安装Jekyll所需的工具链: : 由于Jekyll需要Ruby,RubyGems,GCC,Make,...

    bora-ajudar:从布局使用React创建一个静态网站

    该项目是通过引导的。... 使用AJAX请求获取数据与API后端集成节点Ruby on Rails 在开发中代理API请求配置代理后出现“无效的主机头”错误手动配置代理配置WebSocket代理在开发中使用HTTPS 在服务器上生成动态&lt;met

Global site tag (gtag.js) - Google Analytics