Springboot 项目使用 undertow 替换 tomcat
jetty、undertow 还有 tomcat 都是 Springboot 中常见的 web 服务器。网上提到通过使用 undertow 替换 tomcat 可以一定程度上的提高性能,当然也有人做测试反驳的。这里不讨论各个 web 容器性能到底如何,那需要实践出真知。现在先尝试替换操作。
百度了一下替换相当的简单,tomcat 是从 spring-boot-starter-web
中默认引入的,所以先排除,之后再引入 undertow 即可。
Springboot:2.7.18
<!-- springboot web 操作包,请求、路由、返回数据等 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- springboot undertow 容器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<!-- <scope>test</scope>-->
</dependency>
一开始看到是一个 starter 的依赖,所以直接复制了 spring-boot-starter-test
改的名称,忘记去除掉 scope 标签,导致出现了下面的两种错误。
一个是更新 mavan 依赖后,提示 import javax.servlet.*;
不存在。通过引入 javax.servlet-api
依赖可以暂时解决报错问题。另外还在一些博主的文章里看到引入 undertow-servlet
,但打开依赖项树状图可以看到,undertow-servlet
本就是 undertow
的子依赖,但就这样在外部单独引入,javax.servlet
不存在的报错确实消失了。当时没搞懂问题所在,觉得非常的神奇。
<dependency>
<groupId>io.undertow</groupId>
<artifactId>undertow-servlet</artifactId>
</dependency>
另一个是在启动项目的时候,此时如果上面一个问题是通过引入 javax.servlet-api
解决的,
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
那么就会报另一个错:
Description:
Web application could not be started as there was no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.
Action:
Check your application's dependencies for a supported servlet web server.
Check the configured web application type.
意思就是 web 服务器没有启动成功,百度了好一会儿都没有什么解决方案。后面就发现了那个单独引入 undertow-servlet
的博文,测试如果是通过单独引入这个依赖,那么就可以正常启动,没有报错。
之后对比突然反应过来,正常引入 undertow 是不应该有 test
scope 标签的,这会限制依赖项目仅仅参与测试相关的工作,包括测试代码的编译、执行。这也是为什么单独引用 undertow-servlet
就能不报错的原因。
另附使用 jetty 替换 tomcat,内容基本一致:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>