目录
  • 使用Undertow做服务器
    • 说明
    • NIO(非阻塞式输入输出)
    • 快速开始
  • undertow警告Buffer pool was not set on WebSocketDeploymentInfo

    使用Undertow做服务器

    说明

    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中。而整个过程客户端与服务端是非阻塞的也就是异步操作。

    下面是压力测试对比:

    服务器 命中 成功率 吞吐量 平均耗时
    Jetty 11488 100% 96.25 trans/sec 0.00sec
    18393 100% 153.92 trans/sec 0.01sec
    21484 99.99% 179.51 trans/sec 0.01sec
    Undertow 11280 100% 94.02 trans/sec 0.00sec
    19442 100% 163.35 trans/sec 0.01sec
    23277 100% 195.54 tran/sec 0.01sec
    Tomcat 10845 100% 90.95 trans/sec 0.02sec
    21673 99.98% 181 trans/sec 0.01sec
    25084 99.98% 209.10 trans/sec 0.01sec

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

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

    快速开始

    更新pom.xml文件:

            <!--<dependency>-->
                <!--<groupId>org.springframework.boot</groupId>-->
                <!--<artifactId>spring-boot-starter-web</artifactId>-->
            <!--</dependency>-->
     
            <!-- 下面的配置将使用undertow来做服务器而不是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-undertow</artifactId>
            </dependency>

    application.yml配置:

    server:
      port: 8081
      # 下面是配置undertow作为服务器的参数
      undertow:
        # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
        io-threads: 4
        # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
        worker-threads: 20
        # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
        # 每块buffer的空间大小,越小的空间被利用越充分
        buffer-size: 1024
        # 是否分配的直接内存
        direct-buffers: true

    配置比较简单,和tomcat使用基本一样,然后就可以快乐的使用undertow啦~

    undertow警告Buffer pool was not set on WebSocketDeploymentInfo

    看提示让你设置一下buffer pool,不然他就使用默认的

    这个警告不影响使用,但是看着别扭,于是

    根据官方文档,和源码,自定义配置

    /**
     * 功能描述:
     *
     * @author liuchaoyong
     * @version 1.0
     * @date 2019-05-26 21:41
     */
    @Component
    public class CustomizationBean implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
     
        @Override
        public void customize(UndertowServletWebServerFactory factory) {
            factory.addDeploymentInfoCustomizers(deploymentInfo -> {
                WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
                webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 1024));
                deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
            });
        }
    }

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持。 

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。