![](/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.