Undertow 是红帽公司开发的一款基于 NIO 的高性能 Web 嵌入式服务器

说明:

        undertow,jetty和tomcat可以说是javaweb项目当下最火的三款服务器,tomcat是apache下的一款重量级的服务器,不用多说历史悠久,经得起实践的考验。然而:当下微服务兴起,spring boot ,spring cloud 越来越热的情况下,选择一款轻量级而性能优越的服务器是必要的选择。spring boot 完美集成了tomcat,jetty和undertow,本文将通过对jetty和undertow服务器的分析以及测试,来比较两款服务器的性能如何。

  值得一提的是jetty和undertow都是基于NIO实现的高并发轻量级的服务器,支持servlet3.1和websocket。所以,有必要先了解下什么是NIO。

NIO(非阻塞式输入输出)

Channel

Selector

Buffer

Acceptor

  Client和Server只向Buffer读写数据不关注数据的流向,数据通过Channel通道进行流转。而Selector是存在与服务端的,用于Channel的注册以此实现数据I/O操作。Acceptor负责接受所以的连接通道并且注册到Channel中。而整个过程客户端与服务端是非阻塞的也就是异步操作。

Untertow 的特点
Servlet4.0 支持:它提供了对 Servlet4.0 的支持。
WebSocket 支持:对 Web Socket 完全支持,包括JSR-356,用以满足 Web 应用巨大数量的客户端。
嵌套性:它不需要容器,只需通过 API 即可快速搭建 Web 服务器。
灵活性:交由链式Handler配置和处理请求,可以最小化按需加载模块,无须加载多余功能。
轻量级:它是一个 Web 服务器,但不像传统的 Web 服务器有容器概念,它由两个核心 Jar 包组成,加载一个 Web 应用可以小于 10MB 内存。
 

下面是压力测试对比图:

服务器    命中    成功率    吞吐量    平均耗时

从中可以看出在高负载下Undertow的吞吐量高于Jetty而且随着压力增大Jetty和Undertow成功率差距会拉大。而在负载不是太大情况下服务器处理能力差不多,jetty还略微高于Undertow。而tomcat的负载能力似乎和Undertow很接近。

  对比三个服务器发现在Undertow在负载过重情况下比Jetty和Tocmat更加顽强,实践证明在负载继续加大情况下Undertow的成功率高于其它两者,但是在并发不是太大情况下三款服务器整体来看差别不大。

配置:

第一步,添加maven依赖,排除默认tomcat

<!-- 配置 Undertow 容器 -->
			<dependency>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-starter-web</artifactId>
				<!-- 移除掉默认支持的 Tomcat -->
				<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>

第二部: 配置yaml文件

server:
  undertow:
    # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
    # 不要设置过大,如果过大,启动项目会报错:打开文件数过多
    io-threads: 4
    # 阻塞任务线程池, 当执行类似servlet请求阻塞IO操作, undertow会从这个线程池中取得线程
    # 它的值设置取决于系统线程执行任务的阻塞系数,默认值是IO线程数*8
    worker-threads: 20
    # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
    # 每块buffer的空间大小,越小的空间被利用越充分,不要设置太大,以免影响其他应用,合适即可
    buffer-size: 1024
    # 每个区分配的buffer数量 , 所以pool的大小是buffer-size * buffers-per-region
    # 是否分配的直接内存
    direct-buffers: true
  port: 8008

第三部:启动服务

注意:在springboot2.x之后的版本 缺少依赖

***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call the method io.undertow.servlet.api.DeploymentInfo.addServletContainerInitializer(Lio/undertow/servlet/api/ServletContainerInitializerInfo;)Lio/undertow/servlet/api/DeploymentInfo; but it does not exist. Its class, io.undertow.servlet.api.DeploymentInfo, is available from the following locations:

  

It was loaded from the following location:

    file:/C:/Users/Administrator/.m2/repository/io/undertow/undertow-servlet/1.4.25.Final/undertow-servlet-1.4.25.Final.jar


Action:

Correct the classpath of your application so that it contains a single, compatible version of io.undertow.servlet.api.DeploymentInfo

添加依赖:

<dependency>
			<groupId>io.undertow</groupId>
			<artifactId>undertow-core</artifactId>
			<version>2.0.16.Final</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/io.undertow/undertow-servlet -->
		<dependency>
			<groupId>io.undertow</groupId>
			<artifactId>undertow-servlet</artifactId>
			<version>2.0.16.Final</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/io.undertow/undertow-websockets-jsr -->
		<dependency>
			<groupId>io.undertow</groupId>
			<artifactId>undertow-websockets-jsr</artifactId>
			<version>2.0.16.Final</version>
		</dependency>

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐