Reputation: 11
We are comparing the throughput of the spring webflux vs spring mvc for one of our project.
We have service1 and service2. Service1 prepares content and posts it to service2 using webclient. The code below is from service1 which posts content to service2.
Note: Service 2 takes 500ms to process a single request.
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);
}
We did a load test with 200, 300, 500, 1000 concurrent users using jmeter. In all the cases we have received same throughput for both frameworks. Are we doing something wrong here?
I have captured load test stats using Gatling for 1000 users for both mvc and reactive.
Webflux - 1000 users
Spring webflux with 1000 concurrent users
MVC - 1000 users
Spring MVC with 1000 concurrent users
Upvotes: 1
Views: 1094
Reputation: 12021
I wouldn't say you did something wrong, rather this specific use case is not suitable for a hard comparison. Both endpoints rely on first loading something from a disk and then making an HTTP call.
The limiting factor here (I guess) is for both the network call, which takes the same time to finish nonetheless you use WebFlux or the MVC.
The benefit you get from WebFlux is the non-blocking behaviour, which scales better with fewer resources under load.
Something similar was already answered quite well on Quora: https://www.quora.com/Does-Spring-WebFlux-perform-better-than-Spring-MVC
Upvotes: 3