使用 Undertow 作为 Servlet 容器
Spring Boot 默认使用Tomcat作为 Servlet 容器,但Undertow以其出色的性能逐渐获得了更多用户的青睐。
要在 Spring Boot 中使用 Undertow 代替 Tomcat,只需要把 spring-boot-starter-tomcat
从spring-boot-starter-web
starter 中排除,并添加spring-boot-starter-undertow
依赖即可。
<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-undertow</artifactId>
</dependency>
使用Undertow后,启动应用,你应该可以看到一条警告日志。
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.7.4)
...
2022-10-17 11:24:33.234 WARN 13748 --- [ main] io.undertow.websockets.jsr : UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
...
2022-10-17 11:24:33.234 WARN 13748 — [ main] io.undertow.websockets.jsr : UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used
显然,此警告的原因是某些东西没有设置,系统使用了默认设置。
解决方案1,设置WebSocketDeploymentInfo属性
只要通过 WebServerFactoryCustomizer
配置类为 io.undertow.websockets.jsr.WebSocketDeploymentInfo
属性手动设置一个合理的值即可。
import io.undertow.server.DefaultByteBufferPool;
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UndertowServletWebServerFactoryConfiguration implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
@Override
public void customize(UndertowServletWebServerFactory factory) {
factory.addDeploymentInfoCustomizers(deploymentInfo -> {
WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 4096));
deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
});
}
}
解决方案2,直接排除 undertow-websockets-jsr
依赖
如果你的应用程序不使用websocket相关的东西,你可以直接从 spring-boot-starter-undertow
中排除 undertow-websockets-jsr
依赖。
<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-undertow</artifactId>
<!-- 排除 undertow-websockets-jsr 依赖-->
<exclusions>
<exclusion>
<groupId>io.undertow</groupId>
<artifactId>undertow-websockets-jsr</artifactId>
</exclusion>
</exclusions>
</dependency>
经过验证,上述2种方式都有效。
参考: