Hystrix请求合并

来源:互联网 发布:华为万兆网络解决方案 编辑:程序博客网 时间:2024/05/29 15:58
  • 继承HystrixCollapser实现请求合并
    • 1 HystrixCollapser的实现类
    • 2 UserService批量查询接口
    • 3 UserBatchCommand批量查询命令
  • 使用注解方式来实现请求合并

1 继承HystrixCollapser实现请求合并

1.1 HystrixCollapser的实现类

 import com.netflix.hystrix.HystrixCollapser;import com.netflix.hystrix.HystrixCollapserKey;import com.netflix.hystrix.HystrixCollapserProperties;import com.netflix.hystrix.HystrixCommand;import com.szss.demo.orders.service.UserService;import com.szss.demo.orders.vo.UserVO;import java.util.ArrayList;import java.util.Collection;import java.util.List;import java.util.stream.Collectors;public class UserCommandCollapser extends HystrixCollapser<List<UserVO>, UserVO, Long> {    private UserService userService;    private final Long userId;    public UserCommandCollapser(UserService userService, Long userId) {        super(Setter.withCollapserKey(HystrixCollapserKey.Factory.asKey("UserCommandCollapser"))                .andCollapserPropertiesDefaults(HystrixCollapserProperties.Setter().withTimerDelayInMilliseconds(100)));        this.userService = userService;        this.userId = userId;    }    /**    *获取请求参数    */    @Override    public Long getRequestArgument() {        return userId;    }    /**    *合并请求产生批量命令的具体实现    */    @Override    protected HystrixCommand<List<UserVO>> createCommand(Collection<CollapsedRequest<UserVO, Long>> collapsedRequests) {        List<Long> userIds = new ArrayList<>(collapsedRequests.size());        userIds.addAll(collapsedRequests.stream().map(CollapsedRequest::getArgument).collect(Collectors.toList()));        return new UserBatchCommand(userService, userIds);    }    /**    *批量命令结果返回后的处理,需要实现将批量结果拆分并传递给合并前的各原子请求命令的逻辑中    */    @Override    protected void mapResponseToRequests(List<UserVO> batchResponse, Collection<CollapsedRequest<UserVO, Long>> collapsedRequests) {        int count = 0;        for (CollapsedRequest<UserVO, Long> collapsedRequest : collapsedRequests) {            UserVO user = batchResponse.get(count++);            collapsedRequest.setResponse(user);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

HystrixCollapser的抽象定义中有三个泛型

public abstract class HystrixCollapser<BatchReturnType, ResponseType, RequestArgumentType> implements HystrixExecutable<ResponseType>, HystrixObservable<ResponseType> {
  • 1

这个三个泛型分别的含义是: 
- BatchReturnType:createCommand()方法创建批量命令的返回值的类型。 
- ResponseType:单个请求返回的类型。 
- RequestArgumentType:getRequestArgument()方法请求参数的类型。

HystrixCollapserProperties.Setter().withTimerDelayInMilliseconds(100))
  • 1

初始化的时候,指定在100毫秒内发生的请求进行合并。

1.2 UserService批量查询接口

只需要实现批量查询接口,单个查询也是走批量查询。

public class UserService {    private static final Logger LOGGER = LoggerFactory.getLogger(UserService.class);    @LoadBalanced    @Autowired    private RestTemplate restTemplate;    public List<UserVO> findAll(String ids) {        ParameterizedTypeReference<List<UserVO>> responseType = new ParameterizedTypeReference<List<UserVO>>() {        };        ResponseEntity<List<UserVO>> user = restTemplate.exchange("http://users-service/users/{ids}", HttpMethod.GET, null, responseType, ids);        return user.getBody();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

1.3 UserBatchCommand批量查询命令

import com.netflix.hystrix.HystrixCommand;import com.netflix.hystrix.HystrixCommandGroupKey;import com.netflix.hystrix.HystrixCommandKey;import com.szss.demo.orders.service.UserService;import com.szss.demo.orders.vo.UserVO;import org.apache.commons.lang.StringUtils;import java.util.ArrayList;import java.util.List;public class UserBatchCommand extends HystrixCommand<List<UserVO>> {    private UserService userService;    private List<Long> ids;    public UserBatchCommand(UserService userService, List<Long> ids) {        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("UserBatchCommand"))                .andCommandKey(HystrixCommandKey.Factory.asKey("findAll")));        this.userService = userService;        this.ids = ids;    }    @Override    protected List<UserVO> run() throws Exception {        if (ids != null && !ids.isEmpty()) {            return userService.findAll(StringUtils.join(ids.toArray(),","));        }        return new ArrayList<>();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

2 使用注解方式来实现请求合并

    @HystrixCollapser(collapserKey = "UserHystrixCollapser", batchMethod = "findAll", //scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,            collapserProperties = {@HystrixProperty(name = "timerDelayInMilliseconds", value = "100")})    public Future<UserVO> find(Long id) {        throw new RuntimeException("This method body should not be executed");    }    @HystrixCommand(commandKey = "findAll")    public List<UserVO> findAll(List<Long> ids) {        ParameterizedTypeReference<List<UserVO>> responseType = new ParameterizedTypeReference<List<UserVO>>() {        };        String idStr = StringUtils.join(ids, ",");        ResponseEntity<List<UserVO>> user = restTemplate.exchange("http://users-service/users/{ids}", HttpMethod.GET, null, responseType, idStr);        return user.getBody();    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

UserService批量查询接口的实现,如1.2所示。

@HystrixProperty(name = "timerDelayInMilliseconds", value = "100")
  • 1

指定在100毫秒内发生的请求进行合并。

public Future<UserVO> find(Long id)
  • 1

被@HystrixCollapser标注的方法,返回类型必须为Future,使用异步方法,否则无法进行请求合并。

@HystrixCollapser中有scope属性,scope的取值为REQUEST, GLOBAL。 
REQUEST范围只对一个request请求内的多次服务请求进行合并,GLOBAL是多单个应用中的所有线程的请求中的多次服务请求进行合并。

原创粉丝点击