2012-08-04 51 views
0

我有一個Rails 3.2應用程序,客戶端在這裏輪詢服務器中的資源以進行更新。此資源不是資產,而是動態內容。Rails有條件不要在Heroku上正常運行

實施戰略我選擇是通過fresh_when指令中Conditional Get

fresh_when(:etag => @etag, :public => false) #it's a private resource, requires auth etc 

所以,當資源仍然是新鮮的(請求「如果 - 未修改」頭等於資源的當前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)和薄(1.3.1)版本。
  • ,設置 'config.action_controller.perform_caching =假'
  • 卸下機架::緩存中間件(config.middleware.delete 架::緩存)

的原因,我不希望這些多餘的反應是因爲它用不需要的對象刷新來轟炸客戶端應用程序,導致最終用戶嚴重的性能下降。當從服務器返回302頭時,客戶端JavaScript只是睡了一會兒纔再次輪詢。

謝謝

回答

0

問題的根源在於API濫用。此行:

fresh_when(etag: @etag, public: false) 

在開發中按照預期行事,但不在生產中行爲。我認爲Etag/If-Not-Modified頭文件的交換對於這種有條件的get過程來說已經足夠了,所以我不在乎添加'Last-Modified'頭文件。

讀到HTTP 1.1 RFC後說:「HTTP/1.1服務器應該在任何可行的時候發送Last-Modified。」我決定給它一個嘗試:

fresh_when(etag: @etag, public: false, last_modified: @news.updated_at) 

和它的工作在Heroku的!我99%確定缺少這個頭文件會在請求/響應路徑上以某種方式搞亂它們的堆棧(因爲它們在你的dyno的前面有像Varnish和Nginx那樣的其他服務器)