9Hystrix 合并请求 · SpringCloud微服务实战 · 看云

9. Hystrix 合并请求

导航

从前面的内容可以得知,Hystrix 会为方法执行分配线程,线程的切换会消耗服务器的性能,Hystrix 提供了合并请求的功能,再一次请求的过程中,可以将一段时间内相同的请求合并到一个命令中执行,方法中允许不同的参数。合并后可以减少网络的请求,进而提升性。


本节代码地址


合并请求需要实现以下功能:

  • 可以整理请求过来的参数
  • 可以将多个请求合并的处理器

9.1 新建FwHystrixCollapser类

这里我们需要实现集成HystrixCollapser抽象类,并实现里面的方法,按照上面的设想,我们需要实现请求的合并和参数的整理,以实现最终只调用一次请求。笔者发起两次请求,参数的值是不一样的,一起看一下结果吧。


@Slf4j
public class FwHystrixCollapser extends HystrixCollapser<List<String>, String, String> {

    private final String name;

    public FwHystrixCollapser(String name) {
        this.name = name;
    }

    @Override
    public String getRequestArgument() {
        return this.name;
    }

    @Override
    protected HystrixCommand<List<String>> createCommand(Collection<CollapsedRequest<String, String>> requests) {
        return new FwBatchCommand(requests);
    }

    @Override
    protected void mapResponseToRequests(List<String> strings, Collection<CollapsedRequest<String, String>> requests) {
        int count=0;
        for (CollapsedRequest<String, String> request : requests) {
            request.setResponse(strings.get(count++));
        }
    }

    private static final class FwBatchCommand extends HystrixCommand<List<String>> {

        private Collection<CollapsedRequest<String, String>> requests;

        protected FwBatchCommand(Collection<CollapsedRequest<String, String>> requests) {
            super(Setter.withGroupKey(
                    HystrixCommandGroupKey.Factory.asKey("testGroup")
                    ).andCommandKey(
                    HystrixCommandKey.Factory.asKey("testKey")
                    )
            );
            this.requests=requests;
        }

        @Override
        protected List<String> run() throws Exception {
            log.info("real request");
            List<String> response=new ArrayList<>();
            for (CollapsedRequest<String, String> request : requests) {
                response.add("result:"+request.getArgument());
            }
            return response;
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        HystrixRequestContext context = HystrixRequestContext.initializeContext();
        Future<String> tesFuture1 = new FwHystrixCollapser("test1").queue();
        Future<String> tesFuture2 = new FwHystrixCollapser("test2").queue();
        log.info(tesFuture1.get());
        log.info(tesFuture2.get());
        context.shutdown();
    }
}

9.2 运行main方法

可以看到run()方法只执行了一次

15:43:26.169 [hystrix-testGroup-1] INFO com.yisu.hystrix.without.FwHystrixCollapser - real request
15:43:26.173 [main] INFO com.yisu.hystrix.without.FwHystrixCollapser - result:test1
15:43:26.173 [main] INFO com.yisu.hystrix.without.FwHystrixCollapser - result:test2