- 继承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> {
这个三个泛型分别的含义是:
- BatchReturnType:createCommand()方法创建批量命令的返回值的类型。
- ResponseType:单个请求返回的类型。
- RequestArgumentType:getRequestArgument()方法请求参数的类型。
HystrixCollapserProperties.Setter().withTimerDelayInMilliseconds(100))
初始化的时候,指定在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.3 UserBatchCommand批量查询命令
import com.netflix.hystrix.HystrixCommandimport com.netflix.hystrix.HystrixCommandGroupKeyimport com.netflix.hystrix.HystrixCommandKeyimport com.szss.demo.orders.service.UserServiceimport com.szss.demo.orders.vo.UserVOimport org.apache.commons.lang.StringUtilsimport java.util.ArrayListimport java.util.Listpublic 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", 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(); }
UserService批量查询接口的实现,如1.2所示。
@HystrixProperty(name = "timerDelayInMilliseconds", value = "100")
指定在100毫秒内发生的请求进行合并。
public Future<UserVO> find(Long id)
被@HystrixCollapser标注的方法,返回类型必须为Future,使用异步方法,否则无法进行请求合并。
@HystrixCollapser中有scope属性,scope的取值为REQUEST, GLOBAL。
REQUEST范围只对一个request请求内的多次服务请求进行合并,GLOBAL是多单个应用中的所有线程的请求中的多次服务请求进行合并。