Okhttp的Spring deferredResult性能问题

时间:2016-02-22 15:03:54

标签: spring performance spring-mvc okhttp deferred

我正在尝试测试一个基本的阻塞和非阻塞API控制器,它会像下面那样传输OkHttp响应:

@SpringBootApplication
public class HttpProxyServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(HttpProxyServiceApplication.class, args);
    }

    @Bean
    public OkHttpClient okHttpClient() {
        return new OkHttpClient();
    }

    @RestController
    @RequestMapping(path = "/test")
    public static class TestController {
        private static final String URL = ...;

        @Autowired
        private OkHttpClient client;

        @RequestMapping(method = RequestMethod.GET, path = "blocking")
        public void blocking(HttpServletResponse httpServletResponse) throws IOException {
            Request request = new Request.Builder()
                    .url(URL)
                    .build();
            try (ResponseBody body = client.newCall(request).execute().body()) {
                StreamUtils.copy(body.byteStream(), httpServletResponse.getOutputStream());
            }
        }

        @RequestMapping(method = RequestMethod.GET, path = "non-blocking")
        public DeferredResult<ResponseEntity<?>> nonBlocking() {
            Request request = new Request.Builder()
                    .url(URL)
                    .build();

            DeferredResult<ResponseEntity<?>> deferredResult = new DeferredResult<>();

            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Request request, IOException e) {
                    ResponseEntity<Void> responseEntity =
                            new ResponseEntity<>(HttpStatus.SERVICE_UNAVAILABLE);
                    deferredResult.setResult(responseEntity);
                }

                @Override
                public void onResponse(Response response) throws IOException {
                    ResponseEntity<InputStreamResource> responseEntity =
                            new ResponseEntity<>(new InputStreamResource(response.body().byteStream()),
                                                 HttpStatus.ACCEPTED);
                    deferredResult.setResult(responseEntity);
                }
            });
            return deferredResult;
        }
    }
}

重要的事情:我想要传输结果!我不想将整个结果保存在内存中。这就是为什么非阻塞我创建了ResponseEntity<InputStreamResource>

然而,使用在两个API上进行爬网的基本JMeter脚本,非阻塞实际上比阻塞的速度慢

  • 500个帖子

阻止结果:

enter image description here

非阻止结果:

enter image description here

有什么理由吗?

更新1:

新测试

@RequestMapping(method = RequestMethod.GET, path = "non-blocking-2")
public DeferredResult<InputStreamResource> nonBlockingBlocking() throws IOException {
    Request request = new Request.Builder()
            .url(URL)
            .build();

    DeferredResult<InputStreamResource> deferredResult = new DeferredResult<>();
    deferredResult.setResult(new InputStreamResource(client.newCall(request).execute().body().byteStream()));
    return deferredResult;
}

完全阻止类似的结果。所以我不认为性能问题直接来自DeferredResult

0 个答案:

没有答案