The feud between Gateway and spring-boot-starter-web

The reason why I chose this topic is actually related to the pit I stepped on. Speaking of which, this pit is very magical. It involves the incompatibility of the technologies on which Gateway and spring-boot-starter-web rely.

1. Background

SpringCloud version---- Finchley.SR2
SpringBoot version---- 2.0.6.RELEASE
If both in a SpringBoot project If Gateway and spring-boot-starter-web are introduced, an error will be reported when starting the project.

Error starting ApplicationContext. To display the conditions report re-run your application with ‘debug’ enabled.
2019-12-31 10:26:35.211 ERROR 13124 — [ main] o.s.b.d.LoggingFailureAnalysisReporter :


APPLICATION FAILED TO START


Description:
Parameter 0 of method modifyRequestBodyGatewayFilterFactory in org.springframework.cloud.gateway.config.GatewayAutoConfiguration required a bean of type ‘org.springframework.http.codec.ServerCodecConfigurer’ that could not be found.
Action:
Consider defining a bean of type ‘org.springframework.http.codec.ServerCodecConfigurer’ in your configuration.
Process finished with exit code 1

But if spring-boot-starter-web is removed, the Gateway project can be started.

2. Problem analysis

View the console print log:Insert image description here
You can see that the tomcat container under web dependency failed to start, and a nio exception was printed.

3. Root cause analysis

3.1 Cause analysis

The long link of the gateway application is based on netty-webflux when started, and the gateway starts using webflux. However, Spring WebFlux is a new responsive web framework introduced in Spring Framework 5.0. Unlike Spring MVC, it does not require a Servlet API, is fully asynchronous and non-blocking, and implements the Reactive Streams specification through the Reactor project.

Traditional spring-boot-starter-web, its architectural combination [spring-webmvc + Servlet + Tomcat] imperative, synchronous blocking
Responsive spring-webflux framework , its architecture combination [spring-webflux + Reactor + Netty] is responsive, asynchronous and non-blocking

In a web project, there are two different programming frameworks based on each other, which conflict with each other, resulting in an error when the project is started. spring-boot-starter-web and spring-boot-starter-webflux are particularly jealous when they meet. It cannot be configured in the same pom.xml or used in the same project at the same time.
If both Gateway and spring-boot-starter-web are introduced into a project, then the built-in container of spring-boot-starter-web is used by default at startup, which will cause a startup error. Reason for error: spring-boot-starter-web does not support gateway dependency on non-blocking framework.

3.2 The difference between gateway zuul and gateway

Zuul is based on synchronous webmvc (spring-boot-starter-web), while gateway is based on netty-webflux. Gateway startup uses webflux, so gateway and zuul are different.

Zuul: Built on Servlet 2.5, compatible with 3.x, using blocking API and does not support long connections, such as websockets.
Gateway is built in Spring 5+, based on Spring Boot 2.x responsive, non-blocking API. At the same time, it supports websockets and is tightly integrated with the Spring framework

4. Solution

4.1 Exclude web built-in containers

Introduce spring-boot-starter-web to exclude spring-boot-starter-tomcat

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- Maven整个生命周期内排除内置容器,排除内置容器导出成war包可以让外部容器运行spring-boot项目-->
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Or directly remove all references to spring-boot-starter-web in the gateway highlight

4.2 Using spring-webflux module

webflux has a new non-blocking functional Reactive web framework for building asynchronous, non-blocking, event-driven services

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

5. Summary

The ecosystem of Spring Cloud is very rich, and the Spring framework has evolved several times, with synchronous (springmvc) and asynchronous (webflux) appearing, and the new technology webflux is not compatible with SpringMVC. We should pay attention to these evolutions when we are engaged in spring development in Java. The differences are constantly accumulated to avoid mining pits. Today I shared the conflict between gateway and spring-boot-starter-web. If there are any mistakes in the article, please point them out so that we can make progress together in our study.

Guess you like

Origin blog.csdn.net/Scalzdp/article/details/134876898