2011-11-02 29 views
2

我正在使用Dragonfly爲我的Rails應用程序處理已處理的圖像。蜻蜓依靠Rack::Cache將來訪問那些處理過的圖片,這樣Dragonfly won't have to process those images again再次浪費了CPU時間。Rails/Dragonfly/Apache - Rack :: Cache - 如何使用X-Sendfile?

我的問題從這裏開始:如果我是正確的,通過Rack :: Cache發送文件仍然繁忙的Rails進程,然後查看一個30頁的圖像,即使這些圖像有一個小文件大小的頁面將捆綁Rails處理非常快。如果有更多的訪問者來看這個頁面,那麼他們的響應時間會非常緩慢。我如何通過X-Sendfile獲取這些文件?

我已經設置在production.rb以下,但我知道這些都是從Rails的資產,而不是蜻蜓文件:

config.serve_static_assets = false 
config.action_dispatch.x_sendfile_header = "X-Sendfile" 

我知道這架::緩存以某種方式支持X-SENDFILE(可能通過Rack::Sendfile),因爲它produces a body that responds to #to_path。但是,我不知道如何啓用此功能。當我檢查來自機架::緩存文件,我看不到任何X-SENDFILE信息:

Date: Wed, 02 Nov 2011 11:38:28 GMT 
Server: Apache/2.2.3 (CentOS) 
X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.9 
Content-Disposition: filename="2.JPG" 
Cache-Control: public, max-age=31536000 
Etag: "3174d486e4df2e78a5ff9174cacbede5787d4660" 
X-Content-Digest: c174408eda6e689998a40db0aef4cdd2aedb3b6c 
Age: 28315 
X-Rack-Cache: fresh 
Content-Length: 22377 
Status: 200 
Content-Type: image/jpeg 

我知道,基於posts around the net,那我應該看到:

X-Sendfile: /path/to/file 

最後我不知道它的蜻蜓或Rack :: Cache(或兩者),我必須配置。 如何通過X-Sendfile獲得Dragonfly和/或Rack :: Cache服務文件?

信息關於我的設置:

  • 的Rails 3.1.1
  • 客運3.0.9
  • CentOS的
  • SENDFILE模塊安裝,據我所知。我在我的虛擬主機配置中指定了XSendFile OnXSendFilePath /path/to/app,並且Apache不抱怨指令XSendFile不存在。

謝謝!

UPDATE 2011年11月6日

基於this old update,只要Rack::Sendfile被放置在的Rack::Cache前面,則X-SENDFILE將被使用。我做到了,這是如何my middleware looks like。該文件,但是,still don't have the X-Sendfile tag。再一次,我不知道這是確定是否啓用X-Sendfile的確定方法,因此我檢查了Passenger隊列。看來,當我訪問一個頁面時,隊列大大受阻。

UPDATE 2011年11月7日

看來這純粹是一個機架::緩存和Rails 3.1的問題。雖然Rack :: Cache支持通過Rack :: Sendfile使用X-Sendfile(就像我上面提到的,Rack :: Cache,自body it returns is a subclass of File以來使用Disk EntityStore以來的響應_ to_path),Rails 3.1使用它自己的存儲解決方案。 Rails 3。1使用ActiveSupport::Cache::FileStore,如果您未在production.rb文件中指定任何內容,則默認設置此項。

FileStore的問題在於它返回的主體是要向上遊發送的響應的一部分,因爲該主體不響應to_path。身體是ActiveSupport::Cache::Entry的一個實例。您可以看到here,當FileStore被要求讀取一個緩存文件時,它通過File.open('/path/to/file') {|f| Marshal.load(f) }讀取它,它返回Entry的一個實例。最終通過上游並返回給客戶端的值是Entry#value

我的問題

爲了幫助我決定我是否應該修補這個,還是讓Rails的使用機架::緩存自己的磁盤店不是,我有一些問題:

  1. 有什麼原因Rack :: Cache自己的存儲解決方案不適用於Rails 3.1?爲什麼Rails有它自己的?
  2. 是否有理由使用元帥?是否有理由將數據的字節流反向傳回?

我深入到了比平時更深的地步,如果我正確地理解了事情,我會感到驚訝。我希望能找到答案!

+0

我問過周圍,發送電子郵件到Rails用戶組,但沒有找到答案。是的,Varnish在開始時聽起來像是過度殺傷性的,但爲了讓X-Sendfile能夠正常工作,我需要進行所有更改,安裝Varnish會更簡單。 –

回答

1

作爲Varnish的替代品,您可以使用Apache的mod_disk_cache。因爲您已經在運行Apache,所以設置起來會更少。

1

我最終得到這個工作,雖然與nginx &獨角獸,而不是Apache &乘客。

正如您在your Github issue中指出的那樣,您可以將Rack :: Cache切換回使用其標準文件:/ store而不是rails:/ store,這將允許響應響應to_path

config.action_dispatch.rack_cache = { 
    :verbose  => true, 
    :metastore => URI.encode("file:/PATH/TO/CACHE/STORE"), 
    :entitystore => URI.encode("file:/PATH/TO/CACHE/STORE") 
} 

蜻蜓做到這一點的發展,如果你喜歡,你仍然可以做到這一點在生產。這樣做需要注意的是,如果您使用任何使用Rack :: Cache的Rails緩存功能,緩存條目將存儲在該存儲中而不是標準的Rails中,因此如果您需要手動清除任何這些條目。

然後您還需要確保使用config.action_dispatch.x_sendfile_header參數在Rack的前面插入Rack :: Sendfile中間件。沒有config參數,Rack :: Sendfile不會添加標題。

config.middleware.insert 0, Rack::Sendfile, config.action_dispatch.x_sendfile_header 

My Gist在production.rb和我的nginx模板中顯示了我的相關行。應該很容易適應與Apache X-Sendfile模塊一起工作。

還有一兩件事要注意,如果你正在測試這一點,就是如果你只通過捲曲發送HEAD請求例如,你不會得到相關的X-SENDFILE頭中的響應,機架::緩存實際上不會發送主體的頭部請求,所以Rack :: Sendfile沒有什麼可以撥打to_path