【发布时间】:2012-08-04 01:26:08
【问题描述】:
我有一个 Rails 3.2 应用程序,其中客户端轮询服务器中的资源以获取更新。此资源不是资产,而是动态内容。
我选择的实现策略是 Conditional Get 通过 fresh_when 指令:
fresh_when(:etag => @etag, :public => false ) #it's a private resource, requires auth etc
所以,当资源还是新鲜的(请求'If-Not-Modified'标头等于资源当前的ETag)时,服务器只返回一个304标头。
Started GET "/news/4fe13e74aa5e7d3d70000001"
Processing by NewsController#show as JSON
Parameters: {"id"=>"4fe13e74aa5e7d3d70000001"}
Completed 304 Not Modified
当资源不再新鲜时,我们在响应正文中有状态 200 和资源的最新版本:
Started GET "/news/4fe13e74aa5e7d3d70000001"
Processing by NewsController#show as JSON
Parameters: {"id"=>"4fe13e74aa5e7d3d70000001"}
Rendered news/show.json.rabl (8.1ms)
Completed 200 OK in 14ms
在开发环境中,这非常有效。问题在于生产环境(Heroku Cedar Stack)。在这种情况下,响应总是 200,正文中包含完整的对象表示:
2012-08-03T21:44:33+00:00 heroku[router]: GET blah.com/news/4fa43b428b91cd0001000002 dyno=web.1 queue=0 wait=0ms service=22ms status=200 bytes=2105
2012-08-03T21:44:33+00:00 app[web.1]: Started GET "/news/4fa43b428b91cd0001000002"
2012-08-03T21:44:33+00:00 app[web.1]: cache: [GET /news/4fa43b428b91cd0001000002] miss
2012-08-03T21:44:33+00:00 heroku[nginx]: 187.38.19.138 - - [03/Aug/2012:21:44:33 +0000] "GET /news/4fa43b428b91cd0001000002 HTTP/1.1" 200 665 "http://www.bla.com/news/4fa43b428b91cd0001000002" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.57 Safari/537.1"
从外观上看,这个请求并没有到达 Rails 控制器(实际评估新鲜度的地方),而是通过 heroku 的路由器和缓存层。
到目前为止我尝试过的:
- 双重检查 Rails (3.2.1) 和 Thin (1.3.1) 版本 环境。
- 设置“config.action_controller.perform_caching = false”
- 删除 Rack::Cache 中间件 (config.middleware.delete 机架::缓存)
我不想要这些冗余响应的原因是因为它会用不需要的对象刷新来轰炸客户端应用程序,从而严重影响最终用户的性能。当服务器只返回一个 302 标头时,客户端 JavaScript 在再次轮询之前只是休眠一段时间。
谢谢
【问题讨论】:
标签: ruby-on-rails-3 http heroku etag