You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rails中实现全后端缓存?能否临时缓存所有Rails后端请求?

关于Rails后端缓存的两个问题解答

1. 如何在Rails中实现全后端缓存

Rails提供了多层级的后端缓存方案,可根据业务场景选择:

  • 页面级缓存:直接缓存整个页面的HTML输出,适合静态或极少变动的页面。Rails 4+需手动添加actionpack-page_caching gem,配置后在控制器启用:

    # Gemfile
    gem 'actionpack-page_caching'
    
    # 控制器代码
    class HomeController < ApplicationController
      caches_page :index
    end
    

    缓存文件会存在public目录,后续请求直接返回静态文件,完全跳过Rails处理流程。

  • 动作级缓存:类似页面缓存,但会经过控制器前置过滤器,适合需要权限校验的页面。需依赖actionpack-action_caching gem:

    # Gemfile
    gem 'actionpack-action_caching'
    
    # 控制器代码
    class DashboardController < ApplicationController
      before_action :authenticate_user!
      caches_action :overview
    end
    
  • 片段缓存:缓存页面局部静态区块,适配动态页面中的固定内容。在视图中使用:

    <% cache 'user_profile', expires_in: 1.hour do %>
      <div class="user-profile">
        <%= @user.name %>
        <%= @user.bio %>
      </div>
    <% end %>
    
  • HTTP缓存:通过响应头实现客户端或反向代理缓存,控制器中用fresh_when或stale?配置:

    class PostsController < ApplicationController
      def show
        @post = Post.find(params[:id])
        fresh_when last_modified: @post.updated_at, etag: @post
      end
    end
    

    浏览器或CDN会依据Last-Modified和ETag判断是否使用缓存。

2. 是否可以临时缓存Rails后端的所有请求?

可以实现,核心是通过自定义Rack中间件或临时缓存策略拦截请求,返回缓存响应,适合开发阶段前端快速重载页面的场景:

方案1:自定义Rack中间件临时缓存所有响应

创建中间件,仅在开发环境启用:

# config/initializers/total_cache_middleware.rb
class TotalCacheMiddleware
  def initialize(app)
    @app = app
    @cache = {}
  end

  def call(env)
    request_key = "#{env['REQUEST_METHOD']}#{env['PATH_INFO']}"
    if @cache.key?(request_key) && Rails.env.development?
      @cache[request_key]
    else
      response = @app.call(env)
      @cache[request_key] = response
      response
    end
  end
end

# 开发环境加载中间件
if Rails.env.development?
  Rails.application.config.middleware.insert_before 0, TotalCacheMiddleware
end

第一次请求会正常走后端逻辑并缓存响应,后续请求直接返回缓存内容,重启服务器即可清空缓存。

方案2:利用Rails缓存存储临时缓存所有动作

在ApplicationController中添加临时缓存逻辑:

# app/controllers/application_controller.rb
before_action :cache_all_requests, if: -> { Rails.env.development? && params[:use_total_cache] }

def cache_all_requests
  cache_key = "#{request.method}#{request.path}"
  if fragment_exist?(cache_key)
    render html: read_fragment(cache_key)
    return
  end
  write_fragment(cache_key, response.body)
end

访问时带上?use_total_cache=1参数即可触发全局缓存,去掉参数恢复正常请求。

这种临时缓存仅适合开发阶段验证前端效果,切勿在生产环境启用,会导致数据更新无法同步。

内容的提问来源于stack exchange,提问作者Ruslan Coroliov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 06:25:21