一 介紹緩存
在高併發的場景之下,Hystrix中提供了請求緩存的功能,能夠方便地開啓和使用請求緩存來優化系統,達到減輕高併發時請求線程的消耗、下降請求響應時間的效果。願意瞭解源碼的朋友直接求求交流分享技術:二一四七七七五六三三併發
二開啓請求緩存功能ide
在實現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); } }
三 清理失效緩存功能this
使用請求緩存時,若是隻是讀操做,那麼不須要考慮緩存內容是否正確的問題,可是若是請求命令中還有更新數據的操做,那麼緩存中的數據就須要咱們在進行寫操做時進行及時處理,以防止讀操做的請求命令獲取到失效的數據。線程
在Hystrix中,能夠經過HystrixRequestCache.clear()方法來進行緩存的清理。code
例如:
對象
//當咱們對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; } } }
總體代碼結構以下:blog