什麼是ESI
ESI的全稱是Edge Side Includes,是一個基于XML的标記語言,目的是在HTTP中組裝各種資源。是由Oracle和Akamai等公司提議的,在W3C的網站也可以找到相關規格說明,最新的是2001年的了,也不是什麼新東西。傳統的cache技能基本都已頁面為機關進行緩存,問題就是頁面部分的動态内容可能比較多,而且是每個用戶端的内容都不一樣(比如個人的登入資訊,歡迎xxx等。),緩存比較困難。ESI為了能把頁面的一部分進行緩存,使用基于XML的标記語言,來描述對page内個内容的緩存情況。這樣,伺服器(緩存部分)就可以隻緩存共同部分了。
ESI有點類似SSI,但是它比SSI功能更豐富。
目前支援/實作ESI的開源伺服器包括Squid,Mongrel-ESI等,商用的有Oracle和Akamai的伺服器。
要在Rails裡支援ESI需要安裝兩個插件,一個是Mongrel用的插件Mongrel-ESI,一個是Rails用來處理ESI标記(tag)的fragmentFu。兩個軟體都可以在http://mongrel-esi.googlecode.com找到。
如何安裝一下Mongrel-ESI我就不說了,因為我也沒有裝過,下面的代碼我都沒有試驗過。
下面來看一下ESI的代碼,下面是一個測試的例子(轉自http://blog.tkmr.org/tatsuya/show/368-rails-10-esi,日文)
- cd /home/my/rails/app/path
- ----index.html-----
- <h1>Welcome ESI!!</h1>
- <p><esi:include src="/welcome/now" max-age="45"/></p>
esi标記裡的就是ESI的内容了,應該比較好了解,max-age的意思就是頁面緩存保留的時間,這裡的話每45秒緩存就會被更新一次。
再來看看控制器裡的代碼:
- ./script/generate controller welcome now
- ----welcome_controller.rb----
- def now
- render :text => "#{Time.now}"
- end
啟動Mongrel_esi:
- mongrel_esi start
- ** Starting Mongrel listening at 0.0.0.0:2000
然後就可以去浏覽器裡看看了,是不是45秒那個顯示的時間才更新一次。
上面的例子是标準的ESI寫法,當然Rails中這樣寫就有點累了,這個時候就需要fragmentFu這個Rails的plugin了。
在ERB裡,寫法是這樣的:
- ./script/plugin install http://mongrel-esi.googlecode.com/svn/trunk/plugin/fragment_fu
- ----/app/view/welcome/index.html.erb----
- <h1>Welcome ESI!!</h1>
- <p><%= render :esi => {:action => "now"}, :ttl => 45.seconds %> </p>
ttl這個名字比較親切。
當然,ESI裡面也能使用Cookie或者Http的request資料:
- #query string
- <p><%= render :esi => "/users/name/$(QUERY_STRING{my_name})" %> </p>
- #Cookie
- <p><%= render :esi => "/users/home/$(HTTP_COOKIE{UserID})" %> </p>
除此之外,ESI還有異常處理機能。因為ESI指令的include可以指向别的位址,是以,取得cache内容也可能失敗。
比如下面的代碼(來自http://revolutiononrails.blogspot.com/2007/08/advanced-rails-caching-on-edge.html
)
- <esi:try>
- <esi:attempt>
- <esi:include src="/latest" max-age="5" timeout="1"/>
- </esi:attempt>
- <esi:except>
- <esi:include src="http://static.foo.com/latest" max-age="5" timeout="1"/>
- </esi:except>
- </esi:try>
這個也應該比較好了解,如果嘗試1秒内取得不到/latest的話,cache伺服器就會放棄,而去取靜态頁面的内容。
另一不錯的功能就是Invalidation,就是使已有的cache的内容失效,因為它cache的内容已經被更新過了。在Rails自帶的cache功能裡需要在action調用失效方法的,或者用sweeper回調。ESI則有invalidate指令:
- <esi:invalidate>
- <?xml version="1.0"?>
- <!DOCTYPE INVALIDATION SYSTEM "internal:///WCSinvalidation.dtd">
- <INVALIDATION VERSION="WCS-1.1">
- <OBJECT>
- <BASICSELECTOR URI="/foo/bar/baz"/>
- <ACTION REMOVALTTL="0"/>
- </OBJECT>
- </INVALIDATION>
- </esi:invalidate>
參考連結:
http://revolutiononrails.blogspot.com/2007/08/fragmentfu-fun-with-fragments.html
http://revolutiononrails.blogspot.com/2007/08/advanced-rails-caching-on-edge.html
http://www.w3.org/TR/esi-lang
http://blog.tkmr.org/tatsuya/show/368-rails-10-esi
Related posts for the current post:
- LuRuJu 将jude的模型當成Rails的model類使用
- 用Ruby抓取網頁通過ActiveRecord存到資料庫
- acts_as_taggable
- 這段話有問題嗎?
- REST有什麼好的
- Japan RubyKaigi2007的一些圖檔
- DRECOM Award on Rails 2007
- 聽Dave Thomas演講
- Japan Ruby Conf 總結(非正式)
- Japan Ruby Conf 2007 第一天(前半)