WebFlux web and webflux starter

2019-04-15 00:51发布

问题:

I created a Spring boot 2.0.0.M7 project with the webflux starter because I want to use all the asynchronous and the non-blocking capabilities. I added the server.servlet.context-path but it does not work if I don't add the web starter as well.

If I add both starters can I have issues with the non-blocking functionality? I executed some stress tests with Gatling and I have received the same scores removing the web starter or adding it.

Any help with this?

回答1:

If you add both spring-boot-starter-web and spring-boot-starter-webflux to your application, Spring Boot will configure it as a Spring MVC app.

This is intentional as many Spring MVC will get the webflux dependency to leverage the new WebClient in their MVC apps. Also, as of Spring Framework 5, Spring MVC knows how to handle a few cases with Flux at the controller level.

You can always force your choice like this:

SpringApplication app = new SpringApplication(MyApplication.class);
app.setWebApplicationType(WebApplicationType.REACTIVE);
app.run(...);

In your case, this is not about forcing a choice but rather using something that's not supported in WebFlux.

The server.servlet.context-path configuration property is Servlet-specific, so it won't work with WebFlux. Currently Spring Boot does not support war deployment nor multiple web contexts for WebFlux applications. So there's no point in offering such a property.

The runtime model difference between "Servlet-based" and Reactive runtime with Spring can be quite subtle, and I encourage you to watch a talk that describes those choices. The short answer is: if you're using Spring MVC with async types (DeferredResult, Flux or SseEmitter) things will be async but reading and writing will still be blocking.

Properly benchmarking that is quite hard, but the results you're seeing are somehow expected. Running locally server+client, no latency involved, looking at raw throughput - all of those constraints should not be in favour of the reactive model which has a concurrency cost. If anything, this benchmark shows that the reactive stack is quite optimized already, even for non-ideal use cases!