3Hystrix 合并请求注解 · SpringCloud微服务实战 · 看云

3.Hystrix 合并请求注解

导航

本节代码地址


前面入门篇我们已经讲过请求合并,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-ribbonEurekaHystrixRibbonService类中新建合并请求的方法,在一个单个接收方法中加上@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
6a243d6c7b5521c9fd035f4a02a49373_MD5.png

fw-cloud-ribbon-server关掉
486ba77f973a126fb0077503ecca012f_MD5.png