§Play 快取 API
快取資料是現代應用程式中常見的最佳化方式,因此 Play 提供了全球快取。
注意:快取的一個重要重點是,它的行為就像快取一樣:您剛剛儲存的資料可能會消失。
對於快取中儲存的任何資料,都需要制定一個再生策略,以防資料消失。此哲學是 Play 背後的基本原則之一,與 Java EE 不同,Java EE 預期會話會在其生命週期中保留值。
Play 提供一個基於 Caffeine 的 CacheApi 實作,以及一個基於 Ehcache 2.x 的舊版實作。對於處理中的快取,Caffeine 通常是最佳選擇。如果您需要分散式快取,有 memcached 和 redis 的第三方外掛程式。
§匯入快取 API
Play 為快取 API 以及 Caffeine 和 Ehcache 實作提供個別的相依性。
§Caffeine
若要取得 Caffeine 實作,請將 caffeine
加入您的相依性清單
libraryDependencies ++= Seq(
caffeine
)
這也會自動設定執行時期 DI 的繫結,以便元件可注入。
§EhCache
若要取得 EhCache 實作,請將 ehcache
加入您的相依性清單
libraryDependencies ++= Seq(
ehcache
)
這也會自動設定執行時期 DI 的繫結,以便元件可注入。
§自訂快取實作
若要只加入 API,請將 cacheApi
加入您的相依性清單。
libraryDependencies ++= Seq(
cacheApi
)
如果您想為 Cached
輔助函式和 AsyncCacheApi
等定義您自己的繫結,而不需要依賴任何特定的快取實作,則 API 相依性會很有用。如果您正在撰寫自訂快取模組,您應該使用這個。
§存取快取 API
快取 API 由 AsyncCacheApi 和 SyncCacheApi 介面定義,視您是要非同步或同步實作而定,而且可以像其他任何相依性一樣注入到您的元件中。例如
import javax.inject.Inject;
import play.cache.*;
import play.mvc.*;
public class Application extends Controller {
private AsyncCacheApi cache;
@Inject
public Application(AsyncCacheApi cache) {
this.cache = cache;
}
// ...
}
注意:API 故意簡化,以允許插入各種實作。如果您需要更具體的 API,請使用您的快取程式庫提供的 API。
使用這個簡單的 API,您可以在快取中儲存資料
CompletionStage<Done> result = cache.set("item.key", frontPageNews);
您也可以選擇為快取指定過期時間(以秒為單位)
// Cache for 15 minutes
CompletionStage<Done> result = cache.set("item.key", frontPageNews, 60 * 15);
您可以在稍後擷取資料
CompletionStage<Optional<News>> news = cache.get("item.key");
您也可以提供一個 Callable
,如果快取中找不到值,則會產生並儲存該值
CompletionStage<News> maybeCached =
cache.getOrElseUpdate("item.key", this::lookUpFrontPageNews);
注意: getOrElseUpdate
在 EhCache 中並非原子操作,而是實作為 get
,接著從 Callable
計算值,然後 set
。這表示如果有多個執行緒同時呼叫 getOrElse
,則有可能會計算值多次。
要從快取中移除項目,請使用 remove
方法
CompletionStage<Done> result = cache.remove("item.key");
要從快取中移除所有項目,請使用 removeAll
方法
CompletionStage<Done> resultAll = cache.removeAll();
removeAll()
僅在 AsyncCacheApi
中可用,因為很少會想要同步移除快取中的所有元素。預期只有在特殊情況下,才需要將移除快取中所有項目視為管理員操作,而不是應用程式的正常操作的一部分。
請注意,SyncCacheApi 具有相同的 API,只不過它直接傳回值,而不是使用未來值。
§存取不同的快取
可以根據名稱定義和使用具有不同組態的不同快取。要存取不同的快取,請在注入快取時,在相依項上使用 NamedCache 限定詞,例如
import javax.inject.Inject;
import play.cache.*;
import play.mvc.*;
public class Application extends Controller {
@Inject
@NamedCache("session-cache")
SyncCacheApi cache;
// ...
}
如果您想要存取多個不同的快取,則需要告知 Play 在 application.conf
中繫結它們,如下所示
play.cache.bindCaches = ["db-cache", "user-cache", "session-cache"]
定義和組態命名快取取決於您使用的快取實作,以下是使用 Caffeine 組態命名快取的範例。
§使用 Caffeine 組態命名快取
如果您想傳遞一個預設自訂設定,將作為所有快取的備援,您可以透過指定來執行
play.cache.caffeine.defaults = {
initial-capacity = 200
...
}
您也可以透過執行下列動作來傳遞特定快取的自訂設定資料
play.cache.caffeine.user-cache = {
initial-capacity = 200
...
}
§使用 EhCache 設定命名快取
使用 EhCache 實作時,預設快取稱為 play,而且可以透過建立名為 ehcache.xml 的檔案來設定。其他快取可以使用不同的設定,甚至實作來設定。
預設情況下,Play 會嘗試為您建立具有 play.cache.bindCaches
名稱的快取。如果您想在 ehcache.xml
中自行定義它們,您可以設定
play.cache.createBoundCaches = false
§設定執行緒內容
預設情況下,Caffeine 和 EhCache 會將元素儲存在記憶體中。因此,從快取中讀取和寫入資料的速度應該非常快,因為幾乎沒有任何封鎖 I/O。
不過,視快取的設定方式(例如,使用 EhCache 的 DiskStore
),可能會出現封鎖 I/O,而這可能會造成過高的成本,因為即使非同步實作也會封鎖預設執行緒內容中的執行緒。
對於這種情況,您可以設定不同的 Pekko 分派器,並透過 play.cache.dispatcher
設定它,以便快取外掛程式使用它
play.cache.dispatcher = "contexts.blockingCacheDispatcher"
contexts {
blockingCacheDispatcher {
fork-join-executor {
parallelism-factor = 3.0
}
}
}
§Caffeine
使用 Caffeine 時,這將設定 Caffeine 的內部執行器。實際上,設定 play.cache.dispatcher
會設定 play.cache.caffeine.defaults.executor
。如同上述所述,因此您可以為不同的快取設定不同的執行器
play.cache.caffeine.user-cache = {
executor = "contexts.anotherBlockingCacheDispatcher"
...
}
§EhCache
對於 EhCache,Play 會在指定調度程式的執行緒上以 Future 執行任何 EhCache 作業。
§快取 HTTP 回應
您可以使用標準的 Action
組合輕鬆建立一個智慧型快取動作。
提示:Play HTTP
Result
實例可以安全地快取並在稍後重複使用。
Play 提供一個預設內建的輔助程式,適用於標準案例
@Cached(key = "homePage")
public Result index() {
return ok("Hello world");
}
§自訂實作
可以提供快取 API 的自訂實作。請確定您有 cacheApi
相依性。
然後您可以實作 AsyncCacheApi,並在 DI 容器中繫結它。您也可以將 SyncCacheApi 繫結到 DefaultSyncCacheApi,它僅封裝非同步實作。
請注意,removeAll
方法可能不受您的快取實作支援,原因可能是它不可行或會不必要地造成效率不彰。如果是這種情況,您可以在 removeAll
方法中擲回 UnsupportedOperationException
。
若要提供快取 API 的實作,除了預設實作之外,您可以建立自訂限定詞,或重複使用 NamedCache
限定詞來繫結實作。
§將 Caffeine 與您的自訂實作並用
要使用 Caffeine 的預設實作,您需要 caffeine
相依項,而且您必須在 application.conf
中停用 Caffeine 模組自動繫結它
play.modules.disabled += "play.api.cache.caffeine.CaffeineCacheModule"
§與自訂實作並用 EhCache
要使用 EhCache 的預設實作,您需要 ehcache
相依項,而且您必須在 application.conf
中停用 EhCache 模組自動繫結它
play.modules.disabled += "play.api.cache.ehcache.EhCacheModule"
在這個文件中發現錯誤?此頁面的原始碼可以在 這裡 找到。在閱讀 文件指南 之後,請隨時提交拉取請求。有問題或建議要分享嗎?請前往 我們的社群論壇 與社群展開對話。