瘋狂Spring Cloud連載(20)Hystrix緩存與合併請求

 本文節選自《瘋狂Spring Cloud微服務架構實戰》

京東購買地址:https://item.jd.com/12256011.html

噹噹網購買地址:http://product.dangdang.com/25201393.html

Spring Cloud教學視頻http://blog.csdn.net/boxiong86/article/details/78399104

Spring Cloud電子書http://blog.csdn.net/boxiong86/article/details/78488226

緩存與合併請求

緩存註解

6.3章節中,講述了Hystrix的緩存功能,在Spring Cloud中,同樣支持使用緩存,並且可以通過註解來實現。根據前面章節可知,緩存與合併請求功能,需要先初始化請求上下文才能實現。新建一個javax.servlet.Filter,用於創建與銷燬Hystrix的請求上下文,請見代碼清單6-9

代碼清單6-19

codes\06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\HystrixFilter.java

@WebFilter(urlPatterns = "/*", filterName = "hystrixFilter")

public class HystrixFilter implements Filter {

 

public void init(FilterConfig filterConfig) throws ServletException {

}

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

HystrixRequestContext context = HystrixRequestContext

.initializeContext();

try {

chain.doFilter(request, response);

} finally {

context.shutdown();

}

}

public void destroy() {

}

}

編寫服務方法,使用@CacheResult註解進行修飾,請見代碼清單6-20

代碼清單6-20

codes\06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\cache\CacheService.java

@Component

public class CacheService {

 

@CacheResult

@HystrixCommand

public Person getPerson(Integer id) {

System.out.println("執行getPerson方法");

Person p = new Person();

p.setId(id);

p.setName("angus");

return p;

}

}

注意服務方法中,被調用一次就會進行一次控制檯輸出。在控制器的方法中,調用多次getPerson方法,控制器代碼請見代碼清單6-21

代碼清單6-21

codes\06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\InvokerController.java

@RequestMapping(value = "/cache1/{personId}", method = RequestMethod.GET,

produces = MediaType.APPLICATION_JSON_VALUE)

public Person testCacheResult(@PathVariable Integer personId) {

//調用多次服務

for(int i = 0; i < 3; i++) {

Person p = cacheService.getPerson(personId);

System.out.println("控制器調用服務" + i);

}

return new Person();

}

控制器中調用了多次服務方法,也就是用戶發送請求後,會執行多次服務方法,啓動“服務調用者,訪問以下地址:http://localhost:9000/cache1/1,控制檯輸出如下:

執行 getPerson方法

控制器調用服務 0

控制器調用服務 1

控制器調用服務 2

根據輸出結果可知,在一次用戶請求的過程中,服務方法只執行了一次,緩存生效。緩存的註解主要有以下3個:

     @CacheResult該註解修飾方法,表示被修飾的方法返回結果將會被緩存,需要與@HystrixCommand一起使用。

     @CacheRemove用於修飾方法讓緩存失效,需要與@CacheResult的緩存key關聯。

     @CacheKey用於修飾方法參數,表示該參數作爲緩存的key

前面的例子使用了@CacheResult註解,下面的代碼片斷,結合@CacheResult@CacheRemove一起使用:

@CacheResult()

@HystrixCommand(commandKey = "removeKey")

public String cacheMethod(String name) {

return "hello";

}

 

@CacheRemove(commandKey = "removeKey")

@HystrixCommand

public String updateMethod(String name) {

return "update";

}

以上代碼片斷中的cacheMethod方法,使用的緩存key爲“removeKey”,方法updateMethod被調用後,將會刪除key爲“updateMethod”的緩存。關於3個緩存註解更深入的使用,本小節不再贅述,讀者可以自行測試。

合併請求註解

Spring Cloud中,同樣支持合併請求,在一次HTTP請求的過程中,收集一段時間內的相同請求,放到一個批處理命令中執行實現合併請求,同樣需要先初始化請求上下文,具體請參見6.4.4中的Filter。接下來,編寫服務類,請見代碼清單6-22

代碼清單6-22

codes\06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\collapse\CollapseService.java

@Component

public class CollapseService {

 

//配置收集1秒內的請求

@HystrixCollapser(batchMethod ="getPersons", collapserProperties =

{

@HystrixProperty(name = "timerDelayInMilliseconds", value = "1000")

}

)

publicFuture<Person> getSinglePerson(Integer id) {

System.out.println("執行單個獲取的方法");

return null;

}

 

@HystrixCommand

public List<Person> getPersons(List<Integer> ids) {

System.out.println("收集請求,參數數量:" + ids.size());

List<Person> ps = new ArrayList<Person>();

for (Integer id : ids) {

Person p = new Person();

p.setId(id);

p.setName("crazyit");

ps.add(p);

}

return ps;

}

}

代碼清單中,最後真實執行的方法爲“getPersons”,getSinglePerson方法使用了@HystrixCollapser註解來修飾,會收集1秒內調用getSinglePerson的請求,放到getPersons方法中進行批處理控制中調用多次getSinglePerson方法,如代碼清單6-23所示。

代碼清單6-23

codes\06\6.4\spring-hystrix-invoker\src\main\java\org\crazyit\cloud\InvokerController.java

@RequestMapping(value = "/collapse", method = RequestMethod.GET,

produces = MediaType.APPLICATION_JSON_VALUE)

public String testCollapse() throws Exception {

//連續執行3次請求

Future<Person> f1 = collapseService.getSinglePerson(1);

Future<Person> f2 = collapseService.getSinglePerson(2);

Future<Person> f3 = collapseService.getSinglePerson(3);

Person p1 = f1.get();

Person p2 = f2.get();

Person p3 = f3.get();

System.out.println(p1.getId() + "---" + p1.getName());

System.out.println(p2.getId() + "---" + p2.getName());

System.out.println(p3.getId() + "---" + p3.getName());

return "";

}

異步執行了3getSinglePerson方法,啓動“服務調用者”,訪問以下地址:http://localhost:9000/collapse,控制檯輸出如下:

收集請求,參數數量:3

1---crazyit

2---crazyit

3---crazyit

根據輸出結果可知,最終只執行了getPersons方法。相對於直接使用HystrixSpring Cloud中合併請求較爲簡單,合併處理器已經由@HystrixCollapser註解幫我們實現,我們僅關心真正命令的執行即可

 

 

 

 本文節選自《瘋狂Spring Cloud微服務架構實戰》

Spring Cloud教學視頻http://blog.csdn.net/boxiong86/article/details/78399104

Spring Cloud電子書http://blog.csdn.net/boxiong86/article/details/78488226

本書代碼共享地址:https://gitee.com/yangenxiong/SpringCloud

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章