【发布时间】: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 个用户
【问题讨论】:
-
WebFlux(或反应式)不是关于性能改进(除非你开始并行执行),而是关于更智能/更好的资源使用。您可以用更少的资源做更多的事情。允许使您更具可扩展性。此外,您正在从文件系统加载内容(阻塞)并调用外部服务(并再次等待结果阻塞)。所以代码或多或少都在做同样的事情,只是阻止行为。
标签: spring-boot spring-mvc spring-webflux