3Hystrix 合并请求注解 · SpringCloud微服务实战 · 看云
3.Hystrix 合并请求注解
导航
本节代码地址
GitHub: https://github.com/xuyisu/fw-sping-cloud/tree/master/fw-cloud-hystrix/fw-cloud-hystrix-ribbon
GitHub: https://github.com/xuyisu/fw-sping-cloud/tree/master/fw-cloud-ribbon/fw-cloud-ribbon-server
前面入门篇我们已经讲过请求合并,Spring Cloud 中也同样支持请求合并,并且Spring Cloud 提供了一个注解,非常方便处理合并请求。
为了方便演示合并请求,我们需要在fw-cloud-ribbon-server里添加一个接收方法,用于接收id的集合。
3.1 提供者新建方法
@GetMapping("/list")
public List<User> getUserById(String ids, HttpServletRequest req){
List<User> list=new ArrayList<>();
String[] splitIds = ids.split(",");
for (String id : splitIds) {
String url = req.getRequestURL().toString();
User user = userService.getUserById(Long.valueOf(id));
user.setRemark(user.getRemark()+":提供服务的是:"+url);
list.add(user);
}
return list;
}
3.2 新建合并请求方法
在fw-cloud-hystrix-ribbon里EurekaHystrixRibbonService类中新建合并请求的方法,在一个单个接收方法中加上@HystrixCollapser注解,用于收集相同请求的数据,然后批量执行。
@HystrixCollapser(batchMethod = "findUsers"
,scope = com.netflix.hystrix.HystrixCollapser.Scope.REQUEST,
collapserProperties = {
@HystrixProperty(name = "timerDelayInMilliseconds",value = "1000")
})
public Future<User> getUserSingle(Long id){
log.info("执行单调调用");
return null;
}
@HystrixCommand(fallbackMethod = "findUsersFailure")
public List<User> findUsers(List<Long> ids){
return restTemplate.getForObject("http://fw-cloud-ribbon-server/user/list?ids=" + StringUtils.join(ids, ","), List.class);
}
public List<User> findUsersFailure(List<Long> ids){
log.info("fallback");
List<User> list=new ArrayList<>();
for (Long id : ids) {
list.add(new User(id, null, null, null, "网络繁忙,请稍后再试,请确认手牌"));
}
return list;
}
fallbackMethod里面返回的数量要和@HystrixCollapser里面接收到的一致,否则汇报下面的错误
Caused by: java.lang.RuntimeException: Failed to map all collapsed requests to response. The expected contract has not been respected. Collapser key: 'getUserSingle', requests size: '3', response size: '1'
合并作用域,默认是REQUEST,就是不会跨越多个请求会话的,只在当前用户请求中合并多次请求为批处理请求。这里改成GLOBAL,就是可以跨越request context,合并不同用户的请求为一次批处理请求。
3.3 添加控制层方法
这里是模拟,一次请求发出3个调用方法,返回是一个数组。同时,如果失败,也会拿到一个失败的数组。
@GetMapping("/user/list")
public List<User> findUsers() throws ExecutionException, InterruptedException {
Future<User> userSingle1 = eurekaRibbonService.getUserSingle(1L);
Future<User> userSingle2 = eurekaRibbonService.getUserSingle(2L);
Future<User> userSingle3 = eurekaRibbonService.getUserSingle(3L);
List<User> list=new ArrayList<>();
list.add(userSingle1.get());
list.add(userSingle2.get());
list.add(userSingle3.get());
return list;
}
3.4重启项目
重启fw-cloud-ribbon-server项目和当前项目,然后Postman 测试localhost:8675/user/list
把fw-cloud-ribbon-server关掉

