在Web应用的性能优化中,HTTP缓存是最直接有效的手段之一。Hanami作为Ruby生态中一个设计优雅的框架,在Hanami::Action模块里内置了一组缓存控制辅助方法,其中Hanami::Action::Cache::Public专门用于将响应标记为公共可缓存资源。这篇文章围绕这个方法的原理、用法和注意事项展开,帮你把缓存策略配置得明明白白。

一、先弄清楚HTTP缓存中public与private的区别
要理解Cache::Public的作用,必须先回到HTTP协议本身。Cache-Control头部的public指令表示该响应可以被任何缓存节点存储,包括浏览器、代理服务器和CDN。与之相对的private指令则表示响应只能被单个用户的浏览器缓存,共享缓存不允许保存副本。
这个区别非常重要。比如一个显示用户个人信息的页面,如果错误地设置了public,CDN可能会把这个响应分发给其他用户,造成严重的信息泄露。反过来,一个静态的样式文件、公开的图片资源或者对所有用户都相同的API响应,设置成public后中间缓存节点就能重复利用副本,大幅减少回源请求。
还有一点容易被忽略:如果响应中已经设置了Authorization头相关的鉴权逻辑,HTTP规范默认这类响应是私有的,此时显式声明public可以覆盖默认行为,但必须确认内容确实不包含敏感数据。
二、在Hanami Action中使用Cache::Public
Hanami把常见的缓存指令封装成了链式调用的方法,代码可读性相当好。下面是一个典型的action示例:
class ShowArticle
include Hanami::Action
def call(params)
article = ArticleRepository.new.find(params[:id])
self.body = render(view: Articles::Show, locals: {article: article})
# 将响应标记为公共缓存,有效期600秒
cache_control :public, max_age: 600
end
end这段代码最终会在响应头中生成Cache-Control: public, max-age=600。方法内部的处理逻辑其实很简单,就是拼接指令字符串并写入响应头。你也可以查看Hanami::Action::Cache::Control类的实现,它负责把:public符号转换为public指令,把max_age:关键字参数转换为max-age=600。
如果需要更细粒度的控制,还可以与其他指令组合:
class ListProducts
include Hanami::Action
def call(params)
self.body = render_products
# 公共缓存,有效期1小时,过期后必须重新验证
cache_control :public, max_age: 3600, must_revalidate: true
end
end生成的头部为Cache-Control: public, max-age=3600, must-revalidate。must-revalidate告诉缓存节点,一旦缓存过期就不能直接返回旧副本,必须向源服务器确认资源是否仍然有效。对于电商商品列表这类时效性要求较高的内容,这个组合很实用。
此外,Hanami还提供了expires_in这样的快捷方法,它和cache_control可以配合使用,但要注意避免重复设置同一个头部,否则后设置的会覆盖先设置的。
三、常见配置误区与验证方法
第一个常见误区是对动态内容不加区分地使用public。比如带登录态的页面,即使内容对所有登录用户相同,也不能标记为公共缓存,因为CDN层面无法区分用户身份。正确的做法是为这类内容使用:private,或者干脆不设置缓存头让框架走默认策略。
第二个误区是只设置public而不指定max-age。没有明确过期时间的公共缓存,各家代理服务器的行为并不一致,有的会使用启发式缓存,实际效果难以预测。建议始终搭配一个明确的max_age值,哪怕是较短的60秒,也能让缓存行为可控。
验证配置是否生效,最简单的办法是用curl命令查看响应头:
curl -I https://your-app-ipipp.com/articles/1
观察输出中的Cache-Control字段是否符合预期。如果使用了CDN,还可以对比回源请求和边缘节点的响应,确认X-Cache之类的命中标记。在开发阶段,建议开启浏览器的开发者工具,在Network面板中查看具体请求的缓存状态,判断命中了强缓存还是协商缓存。
最后一个建议:把缓存策略集中管理。不要在各个action里散落着写缓存参数,可以定义一个公共的模块或者常量,比如统一的PUBLIC_ONE_HOUR = {public: true, max_age: 3600},需要时统一引用。这样当策略需要调整时,改一处即可,避免遗漏。合理使用Hanami::Action::Cache::Public,配合清晰的缓存分层设计,能让应用的响应速度和源站压力都得到明显改善。
HanamiCache-Control公共缓存修改时间:2026-09-04 01:02:40