偶爾在spring4all,看到DiDi關於hystrix請求合併的一篇文章 Spring Cloud Hystrix的請求合併,查閱資料又整理了一下。
具體業務概念,什麼是請求合併?請求合併優缺點?可以參考DiDi的文章,然後我把我使用過程中的問題及解決方法寫出來
程式碼
合併請求服務實現
@HystrixCollapser(batchMethod = "testAll", collapserProperties = {
@HystrixProperty(name = "timerDelayInMilliseconds", value = "3000")
})
public Future<Demo> test(String param) {
return null;
}
@HystrixCommand
public List<Demo> testAll(List<String> params) {
logger.info("合併操作執行緒 --> {} --> params --> {}", Thread.currentThread().getName(), params);
return return restTemplate.getForObject("http://DEMO-SERVICE/demo?params={1}", List.class, StringUtils.join(params, ","));;
}
複製程式碼
對外請求介面定義:
@RequestMapping("/test")
public SysDict test() throws ExecutionException, InterruptedException {
//開啟上下文TheardLocal
HystrixRequestContext context = HystrixRequestContext.initializeContext();
Future<Demo> demo1 = testService.test(RandomUtil.randomNumbers(5));
Future<Demo> demo2 = testService.test(RandomUtil.randomNumbers(5));
System.out.println(demo1.get());
System.out.println(demo2.get());
context.close();
return null;
}
複製程式碼
效果如下:
- 如圖兩次呼叫Service.test()被合併成一次服務呼叫。
如果我請求兩次介面也就是會呼叫四次Service.test(),那麼會合併成幾次服務呼叫呢?
- 如圖,兩次請求還是被合併成了兩次服務呼叫。
怎麼實現兩次請求,合併成一次服務呼叫?
@HystrixCollapser scope屬性
//所有執行緒的請求中的多次服務請求進行合併。
Scope.GLOBAL;
//預設,對一次請求的多次服務呼叫合併
Scope.REQUEST;
複製程式碼
改造後程式碼:
@HystrixCollapser(batchMethod = "testAll", scope = Scope.GLOBAL, collapserProperties = {
@HystrixProperty(name = "timerDelayInMilliseconds", value = "3000")
})
public Future<Demo> test(String param) {
return null;
}
複製程式碼
改造後效果:
總結
- 這裡單個請求的service 返回的 Future 包裝的物件,如果使用原物件,則是同步請求,不會合並。
- HystrixRequestContext 介面訪問需要開啟上下文物件,其實就是使用TheardLoacl 初始化一個上下文物件。
- 暫時還不支援 feign 整合
- @HystrixCollapser Scope.REQUEST Scope.GLOBAL 合併作用域的區別