您好,登錄后才能下訂單哦!
本篇內容介紹了“Spring Cloud中Hystrix的請求緩存怎么實現”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
如果我們使用了自定義Hystrix請求命令的方式來使用Hystrix,那么我們只需要重寫getCacheKey方法即可實現請求緩存,如下:
public class BookCommand extends HystrixCommand<Book> { private RestTemplate restTemplate; private Long id; @Override protected Book getFallback() { Throwable executionException = getExecutionException(); System.out.println(executionException.getMessage()); return new Book("宋詩選注", 88, "錢鐘書", "三聯書店"); } @Override protected Book run() throws Exception { return restTemplate.getForObject("http://HELLO-SERVICE/getbook5/{1}", Book.class,id); } public BookCommand(Setter setter, RestTemplate restTemplate,Long id) { super(setter); this.restTemplate = restTemplate; this.id = id; } @Override protected String getCacheKey() { return String.valueOf(id); } }
系統在運行時會根據getCacheKey方法的返回值來判斷這個請求是否和之前執行過的請求一樣,即被緩存,如果被緩存,則直接使用緩存數據而不去請求服務提供者,那么很明顯,getCacheKey方法將在run方法之前執行。我現在在服務提供者中打印一個日志,如下:
@RequestMapping(value = "/getbook5/{id}", method = RequestMethod.GET) public Book book5(@PathVariable("id") Integer id) { System.out.println(">>>>>>>>/getbook5/{id}"); if (id == 1) { return new Book("《李自成》", 55, "姚雪垠", "人民文學出版社"); } else if (id == 2) { return new Book("中國文學簡史", 33, "林庚", "清華大學出版社"); } return new Book("文學改良芻議", 33, "胡適", "無"); }
然后我們服務消費者的Controller中來執行這個請求,如下:
@RequestMapping("/test5") public Book test5() { HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey("commandKey"); HystrixRequestContext.initializeContext(); BookCommand bc1 = new BookCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")).andCommandKey(commandKey), restTemplate, 1l); Book e1 = bc1.execute(); BookCommand bc2 = new BookCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")).andCommandKey(commandKey), restTemplate, 1l); Book e2 = bc2.execute(); BookCommand bc3 = new BookCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")).andCommandKey(commandKey), restTemplate, 1l); Book e3 = bc3.execute(); System.out.println("e1:" + e1); System.out.println("e2:" + e2); System.out.println("e3:" + e3); return e1; }
我連著發起三個相同的請求,我們來看看服務提供者的日志打印情況,注意,在服務請求發起之前,需要先初始化HystrixRequestContext。執行效果如下:
小伙伴們看到,上面是服務提供者打印出來的日志,下面是服務消費者打印出來的日志,發起了三個請求,但是服務提供者實際上只執行了一次,其他兩次都使用了緩存數據。
有一種特殊的情況:如果我將服務提供者的數據修改了,那么緩存的數據就應該被清除,否則用戶在讀取的時候就有可能獲取到一個錯誤的數據,緩存數據的清除也很容易,也是根據id來清除,方式如下:
@RequestMapping("/test5") public Book test5() { HystrixCommandKey commandKey = HystrixCommandKey.Factory.asKey("commandKey"); HystrixRequestContext.initializeContext(); BookCommand bc1 = new BookCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")).andCommandKey(commandKey), restTemplate, 1l); Book e1 = bc1.execute(); HystrixRequestCache.getInstance(commandKey, HystrixConcurrencyStrategyDefault.getInstance()).clear(String.valueOf(1l)); BookCommand bc2 = new BookCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")).andCommandKey(commandKey), restTemplate, 1l); Book e2 = bc2.execute(); BookCommand bc3 = new BookCommand(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("")).andCommandKey(commandKey), restTemplate, 1l); Book e3 = bc3.execute(); System.out.println("e1:" + e1); System.out.println("e2:" + e2); System.out.println("e3:" + e3); return e1; }
小伙伴們注意,這里我們執行完第一次請求之后,id為1的數據就已經被緩存下來了,然后我通過HystrixRequestCache中的clear方法將緩存的數據清除掉,這個時候如果我再發起請求,則又會調用服務提供者的方法,我們來看一下執行結果,如下:
小伙伴們看到,此時服務提供者的方法執行了兩次,因為我在第一次請求結束后將id為1的緩存清除了。
當然,我們也可以通過注解來開啟緩存,和緩存相關的注解一共有三個,分別是@CacheResult、@CacheKey和@CacheRemove,我們分別來看。
@CacheResult方法可以用在我們之前的Service方法上,表示給該方法開啟緩存,默認情況下方法的所有參數都將作為緩存的key,如下:
@CacheResult @HystrixCommand public Book test6(Integer id,String aa) { return restTemplate.getForObject("http://HELLO-SERVICE/getbook5/{1}", Book.class, id); }
此時test6方法會自動開啟緩存,默認所有的參數都將作為緩存的key,如果在某次調用中傳入的兩個參數和之前傳入的兩個參數都一致的話,則直接使用緩存,否則就發起請求,如下:
@RequestMapping("/test6") public Book test6() { HystrixRequestContext.initializeContext(); //第一次發起請求 Book b1 = bookService.test6(2, ""); //參數和上次一致,使用緩存數據 Book b2 = bookService.test6(2, ""); //參數不一致,發起新請求 Book b3 = bookService.test6(2, "aa"); return b1; }
當然這里我們也可以在@CacheResult中添加cacheKeyMethod屬性來指定返回緩存key的方法,注意返回的key要是String類型的,如下:
@CacheResult(cacheKeyMethod = "getCacheKey2") @HystrixCommand public Book test6(Integer id) { return restTemplate.getForObject("http://HELLO-SERVICE/getbook5/{1}", Book.class, id); } public String getCacheKey2(Integer id) { return String.valueOf(id); }
此時默認的規則失效。
當然除了使用默認數據之外,我們也可以使用@CacheKey來指定緩存的key,如下:
@CacheResult @HystrixCommand public Book test6(@CacheKey Integer id,String aa) { return restTemplate.getForObject("http://HELLO-SERVICE/getbook5/{1}", Book.class, id); }
這里我們使用@CacheKey注解指明了緩存的key為id,和aa這個參數無關,此時只要id相同就認為是同一個請求,而aa參數的值則不會作為判斷緩存的依據(這里只是舉例子,實際開發中我們的調用條件可能都要作為key,否則可能會獲取到錯誤的數據)。如果我們即使用了@CacheResult中cacheKeyMethod屬性來指定key,又使用了@CacheKey注解來指定key,則后者失效。
這個當然是用來讓緩存失效的注解,用法也很簡單,如下:
@CacheRemove(commandKey = "test6") @HystrixCommand public Book test7(@CacheKey Integer id) { return null; }
注意這里必須指定commandKey,commandKey的值就為緩存的位置,配置了commandKey屬性的值,Hystrix才能找到請求命令緩存的位置。舉個簡單的例子,如下:
@RequestMapping("/test6") public Book test6() { HystrixRequestContext.initializeContext(); //第一次發起請求 Book b1 = bookService.test6(2); //清除緩存 bookService.test7(2); //緩存被清除,重新發起請求 Book b2 = bookService.test6(2); //參數一致,使用緩存數據 Book b3 = bookService.test6(2); return b1; }
“Spring Cloud中Hystrix的請求緩存怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。