Ruby on Rails 作為解釋型語言框架,在大型可擴展應用中必須依賴完善的緩存體系。本文系統梳理 Rails 可用的緩存策略,並以 ChangingThePresent.org 實戰案例展示如何組合使用多層緩存。
ChangingThePresent.org 面臨四類典型緩存場景:


完全靜態頁面(如用戶協議)移除所有動態元素,由 Apache 直接服務,完全繞過 Rails。圖片等靜態資源同樣由 Apache 處理,後期引入 Panther Express CDN 加速,通過 HTTP Cache-Control 頭控制過期:
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
適合不常變化的動態頁面(Blog、公告)。啟用極簡:
class AboutController < ApplicationController caches_page :privacy_policy, :user_agreement end
失效使用 `expire_page` 或定時清理文件。注意事項:
class CauseSweeper < ActionController::Caching::Sweeper
observe Cause
def after_save(record)
expire_page(:controller => 'causes', :action => 'show', :id => record.id)
record.nonprofits.each do |nonprofit|
expire_page(:controller => 'nonprofits', :action => 'show', :id => nonprofit.id)
end
end
end
需認證的頁面可用動作緩存,Rails 仍會執行控制器的 before_filter:
caches_action :secret_page, :secret_list
速度較頁面緩存慢,但保留應用層邏輯控制權。
緩存頁面局部,如首頁禮物列表區塊:
<% cache 'gifts_index' do %>
<h3>...</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 %>
緩存鍵可用模型 permalink 動態生成:`<% cache @cause.permalink(params[:id]) do %>`
使用 `timed_fragment_cache` 插件簡化失效邏輯:
def index
when_fragment_expired 'causes_list', 15.minutes.from_now do
@causes = Cause.find_all_ordered
end
end
容忍數據短暫陳舊,換取極簡的緩存管理。
片段緩存默認存文件系統,生產環境需換用 Memcached:
config.action_controller.perform_caching = true
memcache_options = {
:c_threshold => 10_000,
:compression => false,
:namespace => 'igprod',
:ttl => 300
}
CACHE = MemCache.new memcache_options
基於內存、網絡分佈,兼顧速度與擴展性。
緩存單行查詢結果(如用戶對象):
Class Cause < CachedModel
原理:攔截 `find(id)` 等單行查詢,優先從 Memcached 讀取。不緩存複雜關聯查詢,避免結果集一致性難題。
ChangingThePresent.org 核心策略:
這套組合拳有效彌補了 Ruby 解釋執行的性能短板,支撐了高併發慈善門戶的穩定運行。下一篇將深入數據庫優化技巧。