![](/img/trans.png)
[英]Spring Web MVC vs Spring WebFlux. Blocking and Non-blocking
[英]How to take advantage of non-blocking requests in Spring Web MVC Controllers
我试图证明在Spring MVC中使用响应流的优势。 为此,我有一台运行有两个端点的小型Jetty服务器:
/normal
返回一个POJO /flux
返回包裹在Mono
的相同对象 然后,我启动一个客户端,并在这些端点之一中发起数千个同时请求。 我希望第二个端点出现的错误更少,因为第二个端点是异步处理的。 但是,有时我会在启用了异步的端点上看到更多错误; 在这两种情况下,都会Connection refused: no further information
60- 90%的Connection refused: no further information
错误Connection refused: no further information
。
我在这里做错了,或者我不太明白。 Connection refused
只是我希望避免的那种事情。
这是我来自服务器的代码。 在normal
情况下,我实际上使用.sleep()
阻塞线程:
@Controller
public class FluxController {
@GetMapping(value = "/normal", produces = MediaType.APPLICATION_JSON_VALUE)
public Map normal() throws Exception {
Thread.sleep(randomTime());
return Collections.singletonMap("type", "normal");
}
@GetMapping(value = "/flux", produces = MediaType.APPLICATION_JSON_VALUE)
public Mono<Map> flux() {
return Mono.delay(Duration.ofMillis(randomTime()))
.map(x -> Collections.singletonMap("type", "flux"));
}
private static long randomTime() {
return ThreadLocalRandom.current().nextLong(200, 1000);
}
}
该服务器通过Maven在Jetty 9.4.15上运行,并且web.xml定义为:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
我的客户使用Spring WebClient:
public class ClientApplication {
private static final String ENDPOINT = "normal";
private static final int REPETITIONS = 10_000;
public static void main(String[] args) {
WebClient client = WebClient.create("http://localhost:8080");
AtomicInteger errors = new AtomicInteger(0);
List<Mono<Response>> responses = IntStream.range(0, REPETITIONS)
.mapToObj(i -> client.get()
.uri(ENDPOINT)
.retrieve()
.bodyToMono(Response.class)
.doOnError(e -> errors.incrementAndGet())
.onErrorResume(e -> Mono.empty())
)
.collect(Collectors.toList());
Mono.when(responses)
.block();
System.out.println(String.format("%-2f %% errors", errors.get() * 100.0 / REPETITIONS));
}
static class Response {
public String type;
}
}
与此处问题类似的前提: WebFlux异步处理 。 主要区别在于我正在测试错误率或同步连接数。 我不希望速度增加。
事实证明,尽管Servlet 3.1规范支持非阻塞IO,但Spring MVC却不支持。 要充分利用反应式API,必须使用WebFlux。 请参阅此处以获取更多信息: https : //youtu.be/Dp_aJh-akkU?t=1738 。
此图演示了与Webflux(右侧)相比,Spring MVC(左侧)如何工作。
我使用加特林(Gatling)进行了更多测试,结果相似:两者花费的时间大致相同,异步的可靠性稍差。 但是,我确实注意到一个半可复制的差异:异步结果有时响应更快:
50%:33.6 s 95%:35.4 s
50%:6.51 s 95%:49.5 s
我仍然不清楚在Spring MVC中使用异步调用(例如DeferredResult)或Reactive Streams API的优势。 因此,如果有人能够用具体的用例来澄清这一点,将不胜感激。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.