【问题标题】:why my spring webflux vs spring mvc load test throughput is same?为什么我的 spring webflux 与 spring mvc 负载测试吞吐量相同?
【发布时间】:2020-06-24 03:55:11
【问题描述】:

我们正在为我们的一个项目比较 spring webflux 与 spring mvc 的吞吐量。

我们有 service1 和 service2。 Service1 准备内容并使用 webclient 将其发布到 service2。下面的代码来自将内容发布到 service2 的 service1。

注意:服务 2 处理单个请求需要 500 毫秒。

Spring Webflux

@PutMapping(path = "/")
public Mono<String> create() throws Exception {
    ClassPathResource classpathResource = new ClassPathResource("/file.zip");

    MultipartBodyBuilder multipartBodyBuilder = new MultipartBodyBuilder();
    multipartBodyBuilder.part("key", "value");
    multipartBodyBuilder.part("file", classpathResource, MediaType.APPLICATION_OCTET_STREAM);
    MultiValueMap<String, HttpEntity<?>> multiValueMap = multipartBodyBuilder.build();

    return WebClient.create()
    .post()
    .uri(uri)
    .contentType(MediaType.MULTIPART_FORM_DATA)
    .headers(httpHeaders -> httpHeaders.setBearerAuth(token))
    .body(BodyInserters.fromMultipartData(multiValueMap))
    .retrieve()
    .bodyToMono(String.class);
}

Spring MVC

@PutMapping(path = "/")
public ResponseEntity<String> create() throws Exception {
    String response = null;
    ClassPathResource classpathResource = new ClassPathResource("/file.zip");

    try (InputStream zipInputStream = new BufferedInputStream(classpathResource.getInputStream())) {

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.setBearerAuth(token);

        LinkedMultiValueMap<String, String> fileMap = new LinkedMultiValueMap<>();
        ContentDisposition contentDisposition = ContentDisposition.builder("form-data").name("file").filename("file")
                .build();
        fileMap.add(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString());
        fileMap.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
        HttpEntity<InputStreamResource> sipEntity = new HttpEntity<InputStreamResource>(
                new InputStreamResource(zipInputStream), fileMap);

        LinkedMultiValueMap<String, String> formatfileMap = new LinkedMultiValueMap<>();
        contentDisposition = ContentDisposition.builder("form-data").name("key")
                .build();
        formatfileMap.add(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString());
        HttpEntity<String> formatEntity = new HttpEntity<String>("value", formatfileMap);

        LinkedMultiValueMap<String, Object> linkedMultiValueMap = new LinkedMultiValueMap<String, Object>();
        linkedMultiValueMap.add("file", sipEntity);
        linkedMultiValueMap.add("key", formatEntity);

        HttpEntity<LinkedMultiValueMap<String, Object>> request = new HttpEntity<LinkedMultiValueMap<String, Object>>(
                linkedMultiValueMap, headers);
        response = restTemplate.postForObject(ingestUrl, request, String.class);
    } 


    return new ResponseEntity<String>(response, HttpStatus.OK);
}

我们使用 jmeter 对 200、300、500、1000 个并发用户进行了负载测试。在所有情况下,我们都收到了两个框架的相同吞吐量。我们在这里做错了吗?

我已经使用 Gatling 为 1000 个用户捕获了 mvc 和响应式的负载测试统计信息。

Webflux - 1000 个用户

Spring webflux with 1000 concurrent users

MVC - 1000 个用户

Spring MVC with 1000 concurrent users

【问题讨论】:

  • WebFlux(或反应式)不是关于性能改进(除非你开始并行执行),而是关于更智能/更好的资源使用。您可以用更少的资源做更多的事情。允许使您更具可扩展性。此外,您正在从文件系统加载内容(阻塞)并调用外部服务(并再次等待结果阻塞)。所以代码或多或少都在做同样的事情,只是阻止行为。

标签: spring-boot spring-mvc spring-webflux


【解决方案1】:

我不会说你做错了什么,而是这个特定的用例不适合硬比较。两个端点都依赖于首先从磁盘加载内容,然后进行 HTTP 调用。

这里的限制因素(我猜)是网络调用,尽管您使用 WebFlux 或 MVC,这需要相同的时间来完成。

您从 WebFlux 中获得的好处是非阻塞行为,它可以通过更少的负载资源更好地扩展。

类似的东西已经在 Quora 上得到了很好的回答:https://www.quora.com/Does-Spring-WebFlux-perform-better-than-Spring-MVC

【讨论】:

    猜你喜欢
    • 2015-02-13
    • 2020-12-31
    • 2012-06-09
    • 2018-03-18
    • 1970-01-01
    • 2021-08-28
    • 2021-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多