如何進(jìn)行SpringCloud-Hystrix緩存與合并請求,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
為市中等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計制作服務(wù),及市中網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、市中網(wǎng)站設(shè)計,以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
緩存在開發(fā)中經(jīng)常用到,我們常用 redis 這種第三方的緩存數(shù)據(jù)庫對數(shù)據(jù)進(jìn)行緩存處理。
在 Hystrix 中也為我們提供了方法級別的緩存。通過重寫 getCacheKey 來判斷是否返回緩存的數(shù)據(jù),getCacheKey 可以根據(jù)參數(shù)來生成。這樣,同樣的參數(shù)就可以都用到緩存了。
改造之前的 MyHystrixCommand,在其中增加 getCacheKey 的重寫實現(xiàn),代碼如下所示。
@Overrideprotected String getCacheKey() {return String.valueOf(this.name); }
在上面的代碼中,我們把創(chuàng)建對象時傳進(jìn)來的 name 參數(shù)作為緩存的 key。
為了證明能夠用到緩存,在 run 方法中加一行輸出,在調(diào)用多次的情況下,如果控制臺只輸出了一次,那么可以知道后面的都是走的緩存邏輯,代碼如下所示。
@Overrideprotected String run() {System.err.println("get data");return this.name + ":" + Thread.currentThread().getName(); }
執(zhí)行 main 方法,發(fā)現(xiàn)程序報錯了,如圖 1 所示:
完整錯誤信息如下:
Caused by: java.lang.IllegalStateException: Request caching is not available. Maybe you need to initialize the HystrixRequestContext?
根據(jù)錯誤提示可以知道,緩存的處理取決于請求的上下文,我們必須初始化 Hystrix-RequestContext。
改造 main 方法中的調(diào)用代碼,初始化 HystrixRequestContext,代碼如下所示。
public static void main(String[] args) throws InterruptedException, ExecutionException { HystrixRequestContext context = HystrixRequestContext.initializeContext(); String result = new MyHystrixCommand("zhangsan").execute(); System.out.println(result); Futurefuture = new MyHystrixCommand("zhangsan").queue(); System.out.println(future.get()); context.shutdown(); }
改造完之后重寫執(zhí)行 main 方法,就可以做正常運行了,輸出結(jié)果如圖 2 所示:
我們可以看到只輸出了一次 get data,緩存生效。
剛剛我們學(xué)習(xí)了如何使用 Hystrix 來實現(xiàn)數(shù)據(jù)緩存功能。有緩存必然就有清除緩存的動作。
當(dāng)數(shù)據(jù)發(fā)生變動時,必須將緩存中的數(shù)據(jù)也更新掉,不然就會出現(xiàn)臟數(shù)據(jù)的問題。同樣地,Hystrix 也有清除緩存的功能。
增加一個支持緩存清除的類,代碼如下所示。
public class ClearCacheHystrixCommand extends HystrixCommand{private final String name;private static final HystrixCommandKey GETTER_KEY = HystrixCommandKey.Factory.asKey("MyKey");public ClearCacheHystrixCommand(String name) {super(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("MyGroup")) .andCommandKey(GETTER_KEY));this.name = name; }public static void flushCache(String name) { HystrixRequestCache.getInstance(GETTER_KEY,HystrixConcurrencyStrategyDefault.getInstance()).clear(name); }@Overrideprotected String getCacheKey() {return String.valueOf(this.name); }@Overrideprotected String run() { System.err.println("get data");return this.name + ":" + Thread.currentThread().getName(); }@Overrideprotected String getFallback() {return "失敗了 "; } }
flushCache 方法就是清除緩存的方法,通過 HystrixRequestCache 來執(zhí)行清除操作,根據(jù) getCacheKey 返回的 key 來清除。
修改調(diào)用代碼來驗證清除是否有效果,代碼如下所示。
public static void main(String[] args) throws InterruptedException, ExecutionException { HystrixRequestContext context = HystrixRequestContext.initializeContext(); String result = new ClearCacheHystrixCommand("zhangsan").execute(); System.out.println(result); ClearCacheHystrixCommand.flushCache("zhangsan"); Futurefuture = new ClearCacheHystrixCommand("zhangsan").queue(); System.out.println(future.get()); }
執(zhí)行兩次相同的 key,在第二次執(zhí)行之前調(diào)用緩存清除的方法,也就是說第二次用不到緩存,輸出結(jié)果如圖 3 所示:
由此可以看出,輸出兩次 get data,這證明緩存確實被清除了??梢园?ClearCache-HystrixCommand.flushCache 這行代碼注釋掉再執(zhí)行一次,就會發(fā)現(xiàn)只輸出了一次 get data,緩存是有效的,輸入結(jié)果如圖 2 所示。
Hystrix 支持將多個請求自動合并為一個請求(代碼如下所示),利用這個功能可以節(jié)省網(wǎng)絡(luò)開銷,比如每個請求都要通過網(wǎng)絡(luò)訪問遠(yuǎn)程資源。如果把多個請求合并為一個一起執(zhí)行,將多次網(wǎng)絡(luò)交互變成一次,則會極大地節(jié)省開銷。
public class MyHystrixCollapser extends HystrixCollapser, String, String> {private final String name;public MyHystrixCollapser(String name) {this.name = name; }@Overridepublic String getRequestArgument() {return name; }@Overrideprotected HystrixCommand
> createCommand(final Collection
> requests) {return new BatchCommand(requests); }@Overrideprotected void mapResponseToRequests(List batchResponse, Collection > requests) { int count = 0;for (CollapsedRequest request : requests) { request.setResponse(batchResponse.get(count++)); } }private static final class BatchCommand extends HystrixCommand > {private final Collection
> requests;private BatchCommand(Collection > requests) {super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")) .andCommandKey(HystrixCommandKey.Factory.asKey("GetValueForKey")));this.requests = requests; }@Overrideprotected List run() { System.out.println(" 真正執(zhí)行請求......"); ArrayList response = new ArrayList ();for (CollapsedRequest request : requests) { response.add(" 返回結(jié)果 : " + request.getArgument()); }return response; } } }
接下來編寫測試代碼,代碼如下所示。
public static void main(String[] args) throws InterruptedException, ExecutionException { HystrixRequestContext context = HystrixRequestContext.initializeContext(); Futuref1 = new MyHystrixCollapser("zhangsan").queue(); Future f2 = new MyHystrixCollapser("zhangsan333").queue(); System.out.println(f1.get() + "=" + f2.get()); context.shutdown(); }
通過 MyHystrixCollapser 創(chuàng)建兩個執(zhí)行任務(wù),按照正常的邏輯肯定是分別執(zhí)行這兩個任務(wù),通過 HystrixCollapser 可以將多個任務(wù)合并到一起執(zhí)行。從輸出結(jié)果就可以看出,任務(wù)的執(zhí)行是在 run 方法中去做的,輸出結(jié)果如圖 4 所示:
看完上述內(nèi)容,你們掌握如何進(jìn)行SpringCloud-Hystrix緩存與合并請求的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!