Pages

搜尋此網誌

2014年3月31日 星期一

grails: 靜態資源或網址加入快取機制

grails: 靜態資源或網址加入快取機制

關於瀏覽器的 cache 機制可以參考下列文章:

其中 Cache Control 與 ETag 這編寫的蠻清楚的,可以清楚知道 Cache 的使用還有相關的屬性差別,基本上對於瀏覽器是否使用 cache 可以從時間的判斷,以及 etag(Entity Tag) 的判斷來決定 server 回傳的 http status 是否為 304,若為 304 則瀏覽器就會讀取 cache 而不會對 server 請求 request。

知道瀏覽器判斷使用 cache 的原理後,以 grails 為例,我們可以加入如下的判斷式:

if (isRequestedFileModified(req)) {
    //get Program and return the image data
} else {
    //file is the same
    response.sendStatus(304)
    return
}

def isRequestedFileModified(req) {
    // check etag and/or compare last modified date/time
}

如此,當我們對後端請求取得資源時,先檢查 etag 有沒有存在,若沒有表示為全新請求,若 etag 相同,可在進一步檢查有沒有更新過或是快取距離最後一次更新是否超過 max-age 所定義的時間。

在實際網站的開發,對於需要大量資源進行計算的請求,或是靜態圖片的讀取,就可以使用快取的機制,來減少 server 的負載,畢竟若不是經常更新的資料,我們可以不用每次都向 server 請求重新取得資源。

雖然上述範例是用 grails 為例,但對於其他語言的實作,不外乎就使檢查 etag 以及最後更新時間,另外若你是使用 grails 進行開發,可以直接使用下列 plugin:

使用此 plugin 你可以事先定義各種 cache 機制的政策比如 plugin 中的範例:

cache.headers.presets = [
    unauthed_page: [shared:true, validFor: 300], // 5 minute refresh window
    authed_page: false, // No caching for logged in user
    content: [shared:true, validFor: 3600], // 1hr on content
    recent_items_feed: [shared: true, validFor: 1800], // 30 minute throttle on RSS updates
    search_results: [validFor: 60, shared: true],
    taxonomy_results: [validFor: 60, shared: true]
]

以便根據不同狀況來有效使用 cache,實際在 controller 中定義 cache 所需屬性可以使用其提供的 DSL 來進行,如下:


def object = s3Service.getObject("${grailsApplication.config.grails.aws.root}/${params.name}/${file}")

withCacheHeaders {
    def image = object
    delegate.lastModified {
        image.getLastModifiedDate()
    }
    etag {
        image.getKey()  
     }
    generate {
        response.contentType = "image/jpeg"
        response.outputStream << image.dataInputStream
    }
}

其中:

  1. delegate.lastModified closure 定義比對時間的資料來源。
  2. etag closure 定義資源識別的方式。
  3. generate closure 會在判斷該請求需要重新取得進行呼叫,若不需要重新取的則會回傳 status 304,使用瀏覽器快取。

補充:若要了解上述 closure 的使用原理可參考下述連結,範例簡單清楚:

可以幫助更進一步理解運作原理。

如此,若要自己撰寫快取機制,或是使用既有的 plugin 都可以在關鍵時刻讓你的網站能夠有更快的效能。

張貼留言