← 返回首页
Springboot配置Undertow
发表时间:2023-10-11 14:36:09
Springboot使用undertow

1.前言

SpringBoot是一个基于Spring框架的快速开发工具,可以帮助开发者快速搭建Web应用接口。而Tomcat则是一款常用的Web服务器,可以用来部署和运行Web应用。一般情况我们都喜欢使用SpringBoot默认自带的Tomcat来运行应用,方便开发部署,节省配置时间。

但是有些互联网大厂可能会限制使用Tomcat,主要出于安全性和性能等其他因素的考虑。那么,我们有没有其他的选择呢?当然有! 一种很好的选择是使用Undertow。

2.Undertow简介

Undertow作为SpringBoot默认集成的三大容器之一(Tomcat、Jetty、Undertow)。首先它是Red Hat公司旗下的开源产品, 由Java语言开发,是一款灵活的高性能Web服务器;不仅支持阻塞IO还支持非阻塞IO,以及监听多端口等特性。由于Undertow通过java语言开发,即在java项目中使用可直接嵌入。而且,Undertow完全支持Servlet和Web Socket,在高并发情况下表现非常出色,总之,Undertow在性能和内存使用方面都优于Jetty和Tomcat。

3.Springboot配置undertow

实现步骤如下:

1).pom.xml

...
<properties>
   <java.version>1.8</java.version>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
   <spring-boot.version>2.6.13</spring-boot.version>
   <mysql.version>8.0.21</mysql.version>
   <hutool.version>5.8.18</hutool.version>
</properties>

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!--排除spring-boot-starter-tomcat-->
    <exclusions>
    <exclusion>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
    </exclusion>
    </exclusions>
    <version>${spring-boot.version}</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>${spring-boot.version}</version>
  </dependency>

  <!-- 添加Undertow容器 -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-undertow</artifactId>
    <version>${spring-boot.version}</version>
  </dependency>

  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
    <version>${spring-boot.version}</version>
  </dependency>
  <!--mysql的驱动-->
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
    <version>${mysql.version}</version>
  </dependency>
  <!--lombok依赖-->
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
  </dependency>
  <!--糊涂工具类依赖-->
  <dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>${hutool.version}</version>
  </dependency>
</dependencies>

2).application.yml

#yml格式配置文档范例
server:
  #端口配置
  port: 8080
  ## 支持的多端口监听,中间用,隔开,连续端口使用-进行链接
  additional-ports: 8888,8889-8892
  #上下文
  servlet:
    context-path: /undertowdemo
#数据源配置
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    #Springboot2.0 的hikari配置
    hikari:
      minimum-idle: 5
      #空闲连接存活最大时间,默认600000(10分钟)
      idle-timeout: 180000
      #连接池最大连接数,默认是10
      maximum-pool-size: 10
      #此属性控制从池返回的连接的默认自动提交行为,默认值:true
      auto-commit: true
      #连接池名称
      pool-name: MyHikariCP
      #此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
      max-lifetime: 1800000
      #数据库连接超时时间,默认30秒,即30000
      connection-timeout: 30000
      connection-test-query: SELECT 1
  jpa:
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    show-sql: true
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL5InnoDBDialect
        format_sql: true
        enable_lazy_load_no_trans: true
        hbm2ddl:
          auto: update

3).添加监听多端口配置。

package com.simoniu.undertowdemo.config;

import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author: simoniu
 * @date: 2022-12-16 18:14
 * @description: 配置undertow监听多端口
 */
@Configuration
public class MultiplePortListerConfig {
    /**
     * 额外端口监听
     */
    @Value("${server.additional-ports}")
    private String additionalPorts;

    @Bean
    public ServletWebServerFactory undertowFactory() {
        UndertowServletWebServerFactory undertowFactory = new UndertowServletWebServerFactory();
        undertowFactory.addBuilderCustomizers(builder -> {
            if (StrUtil.isBlank(additionalPorts)) {
                return;
            }
            String[] ports = additionalPorts.split(",");
            for (String port : ports) {
                if (port.contains("-")){
                    String[] portArr = port.split("-");
                    int start = Integer.parseInt(StrUtil.trim(portArr[0]));
                    int end = Integer.parseInt(StrUtil.trim(portArr[1]));
                    for (int i = start; i<=end; i++){
                        builder.addHttpListener(i, "0.0.0.0");
                    }
                }else {
                    builder.addHttpListener(Integer.parseInt(StrUtil.trim(port)), "0.0.0.0");
                }
            }
        });
        return undertowFactory;
    }
}

4).启动项目,观察输出信息。

2023-10-11 22:30:19.637  INFO 8256 --- [  restartedMain] io.undertow                              : starting server: Undertow - 2.2.20.Final
2023-10-11 22:30:19.641  INFO 8256 --- [  restartedMain] org.xnio                                 : XNIO version 3.8.7.Final
2023-10-11 22:30:19.644  INFO 8256 --- [  restartedMain] org.xnio.nio                             : XNIO NIO Implementation Version 3.8.7.Final
2023-10-11 22:30:19.668  INFO 8256 --- [  restartedMain] org.jboss.threads                        : JBoss Threads version 3.1.0.Final
2023-10-11 22:30:19.698  INFO 8256 --- [  restartedMain] o.s.b.w.e.undertow.UndertowWebServer     : Undertow started on port(s) 8080 (http) 8888 (http) 8889 (http) 8890 (http) 8891 (http) 8892 (http) with context path '/undertowdemo'
2023-10-11 22:30:19.707  INFO 8256 --- [  restartedMain] c.s.u.UndertowdemoApplication            : Started UndertowdemoApplication in 2.051 seconds (JVM running for 3.233)

5).测试监听多端口请求。

4.Undertow 与tomcat性能对比

QPS测试结果对比:

通过测试发现,在高并发系统中,Tomcat相对来说比较弱。在相同的机器配置下,模拟相等的请求数,Undertow在性能和内存使用方面都是最优的。并且Undertow新版本默认使用持久连接,这将会进一步提高它的并发吞吐能力。所以,如果是高并发的业务系统,Undertow是最佳选择。