java B2B2C Springcloud電子商務平臺原始碼------Hystrix的快取使用
阿新 • • 發佈:2018-12-07
一 介紹
在高併發的場景之下,Hystrix中提供了請求快取的功能,可以方便地開啟和使用請求快取來優化系統,達到減輕高併發時請求執行緒的消耗、降低請求響應時間的效果。願意瞭解原始碼的朋友直接求求交流分享技術:二一四七七七五六三三
二開啟請求快取功能
在實現HystrixCommand或HystrixObservableCommand時,通過過載getCacheKey()方法來開啟請求快取。
例如:
public class CommandUsingRequestCache extends HystrixCommand<Boolean> { private final int value; protected CommandUsingRequestCache(int value) { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.value = value; } @Override protected Boolean run() { return value == 0 || value % 2 == 0; } //通過getCacheKey方法中返回的請求快取key值,就能讓該請求命令具備快取功能。此時當不同的外部請求 //處理邏輯呼叫了同一個依賴服務時,Hystrix會根據getCacheKey方法返回的值區分是否是重複請求, //如果它們的cachekey相同時候,那麼該依賴服務值會在第一個請求達到時被真實的呼叫一次,另外一個 //請求則直接從請求快取中返回結果,所以開啟快取有以下好處: //減少重複請求數,降低依賴服務的併發度 //在同一使用者請求的上下文中,相同依賴服務的返回資料始終保持一致。 //請求快取在run()和construct()執行之前生效,所以可以有效減少不必要的執行緒開銷。 @Override protected String getCacheKey() { return String.valueOf(value); } }
三 清理失效快取功能
使用請求快取時,如果只是讀操作,那麼不需要考慮快取內容是否正確的問題,但是如果請求命令中還有更新資料的操作,那麼快取中的資料就需要我們在進行寫操作時進行及時處理,以防止讀操作的請求命令獲取到失效的資料。
在Hystrix中,可以通過HystrixRequestCache.clear()方法來進行快取的清理。
例如:
//當我們對GetterCommand命令實現了請求快取之後,那麼勢必需要為SetterCommand命令實現清理快取,以保證 //prefixStoredOnRemoteDataStore被更新之後,Hystrix請求快取中相同的快取的結果被移除,這樣下一次根據id //獲取prefixStoredOnRemoteDataStore時,不會從快取去獲取資料 public class CommandUsingRequestCacheInvalidation { /* represents a remote data store */ private static volatile String prefixStoredOnRemoteDataStore = "ValueBeforeSet_"; //根據id獲取資料 public static class GetterCommand extends HystrixCommand<String> { private static final HystrixCommandKey GETTER_KEY = HystrixCommandKey.Factory.asKey("GetterCommand"); private final int id; public GetterCommand(int id) { super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GetSetGet")) .andCommandKey(GETTER_KEY)); this.id = id; } @Override protected String run() { return prefixStoredOnRemoteDataStore + id; } @Override protected String getCacheKey() { return String.valueOf(id); } //該方法從預設的Hystrix併發策略中根據GETTER_KEY獲取命令的請求快取物件HystrixRequestCache的例項 //然後再呼叫該請求快取物件的clear方法,對Key為id值的快取內容進行清理。 public static void flushCache(int id) { HystrixRequestCache.getInstance(GETTER_KEY, HystrixConcurrencyStrategyDefault.getInstance()).clear(String.valueOf(id)); } } //用於更新prefixStoredOnRemoteDataStore的值 public static class SetterCommand extends HystrixCommand<Void> { private final int id; private final String prefix; public SetterCommand(int id, String prefix) { super(HystrixCommandGroupKey.Factory.asKey("GetSetGet")); this.id = id; this.prefix = prefix; } @Override protected Void run() { // persist the value against the datastore prefixStoredOnRemoteDataStore = prefix; //在呼叫了寫prefixStoredOnRemoteDataStore之後,增加了對GetterCommand //中靜態方法flushCache的呼叫,以實現對時效快取的清理工作。 GetterCommand.flushCache(id); // no return value return null; } } }
整體程式碼結構如下: