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

Rails 6生产环境每日缓存块失效问题求助

问题排查与解决方案

核心问题分析

生产环境每次请求都刷新名言,说明缓存未正确命中,大概率是时区不一致或缓存键生成逻辑导致,也可能是缓存存储未正常工作。

分步解决方案

1. 统一缓存键的时区基准

Date.today依赖服务器系统时区,而Date.current遵循Rails应用配置的时区,二者不一致会导致缓存键生成错误(比如应用时区为巴黎时区,但服务器是UTC时区,会出现同一自然日生成不同缓存键的情况)。

修改控制器和视图的缓存键生成逻辑,统一使用Date.current并生成固定格式的日期字符串:

# 控制器代码
date_key = Date.current.strftime("%Y-%m-%d")
@quote_of_the_day = Rails.cache.fetch("daily_quote_#{date_key}", expires_in: 1.day) do
  Quote.joins(:quote_tags).where(quote_tags: { id: 1 }).order("RANDOM()").limit(1).first
end
# 视图代码
<% date_key = Date.current.strftime("%Y-%m-%d") %>
<% cache("daily-quote-#{date_key}", expires_in: 24.hours) do %>
  <blockquote>
    <%= @quote_of_the_day.content.html_safe %>
    <figcaption>
      <% if @quote_of_the_day.book.present? %>
        <% if @quote_of_the_day.author.present? %>
          <%= @quote_of_the_day.author %> — <cite><%= @quote_of_the_day.book %></cite>
        <% else %>
          <cite><%= @quote_of_the_day.book %></cite>
        <% end %>
      <% elsif @quote_of_the_day.author.present? %>
        <%= @quote_of_the_day.author %>
      <% end %>
    </figcaption>
  </blockquote>
<% end %>

2. 移除冗余的双重缓存

控制器的Rails.cache.fetch和视图的cache块属于双重缓存,虽功能可行但增加调试复杂度。可简化为只在视图层缓存整个内容块(包含数据查询),减少出错点:

<% cache("daily-quote-#{Date.current.strftime("%Y-%m-%d")}", expires_in: 1.day) do %>
  <% quote = Quote.joins(:quote_tags).where(quote_tags: { id: 1 }).order("RANDOM()").limit(1).first %>
  <blockquote>
    <%= quote.content.html_safe %>
    <figcaption>
      <% if quote.book.present? %>
        <% if quote.author.present? %>
          <%= quote.author %> — <cite><%= quote.book %></cite>
        <% else %>
          <cite><%= quote.book %></cite>
        <% end %>
      <% elsif quote.author.present? %>
        <%= quote.author %>
      <% end %>
    </figcaption>
  </blockquote>
<% end %>

3. 验证Redis缓存连通性

登录生产环境Rails控制台,执行以下命令确认缓存存储是否正常工作:

# 写入测试缓存
Rails.cache.write("cache_test", "ok", expires_in: 30.minutes)
# 读取测试缓存
Rails.cache.read("cache_test")

如果返回"ok",说明Redis缓存正常;如果返回nil,检查Redis地址配置、网络连通性或权限问题——这会导致Rails fallback到进程内内存缓存,不同请求会命中不同进程,表现为缓存不生效。

4. 检查时区配置一致性

在生产控制台执行以下命令,确认应用时区与系统时区是否匹配:

puts "应用时区: #{Rails.configuration.time_zone}"
puts "系统时区: #{Time.now.zone}"
puts "Date.today: #{Date.today.to_s}"
puts "Date.current: #{Date.current.to_s}"

如果Date.today与Date.current返回不同日期,说明时区不一致,必须统一使用Date.current生成缓存键。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 09:48:15