记一次springboot中用undertow的坑

目录
  • springboot中用undertow的坑
    • 本文实验的环境如下
    • 环境准备
    • 使用springboot2.2.11、springboot2.2.12、springboot2.2.13
    • 如果是生产采用了上述几个版本的sringboot
  • springboot需放弃Tomcat,选择Undertow吗?
    • SpringBoot中的Tomcat容器
    • SpringBoot设置Undertow
    • Tomcat与Undertow的优劣对比

springboot中用undertow的坑

场景:准备基于springboot的静态资源实现mp4资源的播放,不同版本的springboot下效果不一样,可能导致正常的资源不可用。本文测试了几个版本,也针对这种情况提出了解决建议,希望对你的工作有所帮助。

众所周知,springboot内置类web中间件,将web服务器管理权交给了容器。在使用时只需要进行申明即可。

本文实验的环境如下

windows7+JDK1.8+Eclipse+Maven3.3.9+SpringBoot2.2.x+Undertow2.2.x

环境准备

第一步、配置maven环境

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.yelang</groupId>
  <artifactId>undertowdemo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>Undertow测试</name>
  <description>Undertow中间件测试</description>

  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.10.RELEASE</version>
        <relativePath />
    </parent>

  <dependencies>
    <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>

    <!-- 添加 Undertow 容器 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-undertow</artifactId>
    </dependency>
  </dependencies>
</project>

第二步、配置申明

# 开发环境配置
server:
  # 服务器的HTTP端口,默认为8080
  port: 8080
  servlet:
    # 应用的访问路径
    context-path: /
  # undertow 配置
  undertow:
    # HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的
    max-http-post-size: -1
    # 以下的配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
    # 每块buffer的空间大小,越小的空间被利用越充分
    buffer-size: 512
    # 是否分配的直接内存
    direct-buffers: true
    threads:
      # 设置IO线程数, 它主要执行非阻塞的任务,它们会负责多个连接, 默认设置每个CPU核心一个线程
      io: 8
      # 阻塞任务线程池, 当执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
      worker: 256
#  # tomcat 配置
#  tomcat:
#    # tomcat的URI编码
#    uri-encoding: UTF-8
#    # tomcat最大线程数,默认为200
#    max-threads: 500
#    # Tomcat启动初始化的线程数,默认值25
#    min-spare-threads: 30

第三步、静态资源映射

package com.yelang.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 通用配置
 * @author wzh
 */
@Configuration
public class ResourcesConfig implements WebMvcConfigurer {

  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    /** 本地文件上传路径 */
    registry.addResourceHandler("/profile/**").addResourceLocations("file:D:/wzh/uploadPath/");
    /** swagger配置 */
    registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
    registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
  }
}

以上代码标注了系统对外开放的静态资源,正常情况下,将资源拷贝到相应的目录下,就可以访问相应资源。

http://localhost:8080/profile/2.mp4

使用springboot2.2.11、springboot2.2.12、springboot2.2.13

这三个版本正常mp4也会无法加载。估计是这几个版本存在一些设置。

如果是生产采用了上述几个版本的sringboot

如果需要对mp4等资源进行预览查看的话。

建议如下:第一、调整springboot的版本,调整到支持的版本。第二、不再使用profile的方式提供视频资源,采用nginx等组件。第三、采用第三方文件系统。第四种、将undertow容器替换成tomcat等其他容器也可以。

小调查:在你的生产环境中,是使用内置容器吗?使用undertow这种nio的容器的有多少?

springboot需放弃Tomcat,选择Undertow吗?

在SpringBoot框架中,我们使用最多的是Tomcat,这是SpringBoot默认的容器技术,而且是内嵌式的Tomcat。

同时,SpringBoot也支持Undertow容器,我们可以很方便的用Undertow替换Tomcat,而Undertow的性能和内存使用方面都优于Tomcat,那我们如何使用Undertow技术呢?本文将为大家细细讲解。

SpringBoot中的Tomcat容器

SpringBoot可以说是目前最火的Java Web框架了。它将开发者从繁重的xml解救了出来,让开发者在几分钟内就可以创建一个完整的Web服务,极大的提高了开发者的工作效率。Web容器技术是Web项目必不可少的组成部分,因为任Web项目都要借助容器技术来运行起来。

在SpringBoot框架中,我们使用最多的是Tomcat,这是SpringBoot默认的容器技术,而且是内嵌式的Tomcat。

SpringBoot设置Undertow

对于Tomcat技术,Java程序员应该都非常熟悉,它是Web应用最常用的容器技术。我们最早的开发的项目基本都是部署在Tomcat下运行,那除了Tomcat容器,SpringBoot中我们还可以使用什么容器技术呢?没错,就是题目中的Undertow容器技术。SrpingBoot已经完全继承了Undertow技术,我们只需要引入Undertow的依赖即可,如下图所示。

配置好以后,我们启动应用程序,发现容器已经替换为Undertow。

那我们为什么需要替换Tomcat为Undertow技术呢?

Tomcat与Undertow的优劣对比

Tomcat是Apache基金下的一个轻量级的Servlet容器,支持Servlet和JSP。Tomcat具有Web服务器特有的功能,包括 Tomcat管理和控制平台、安全局管理和Tomcat阀等。Tomcat本身包含了HTTP服务器,因此也可以视作单独的Web服务器。

但是,Tomcat和ApacheHTTP服务器不是一个东西,ApacheHTTP服务器是用C语言实现的HTTP Web服务器。Tomcat是完全免费的,深受开发者的喜爱。

Undertow是Red Hat公司的开源产品, 它完全采用Java语言开发,是一款灵活的高性能Web服务器,支持阻塞IO和非阻塞IO。由于Undertow采用Java语言开发,可以直接嵌入到Java项目中使用。同时, Undertow完全支持Servlet和Web Socket,在高并发情况下表现非常出色。

我们在相同机器配置下压测Tomcat和Undertow,得到的测试结果如下所示:

QPS测试结果对比:

Tomcat

Undertow

内存使用对比:

Tomcat

Undertow

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

最后

SpingBoot中我们既可以使用Tomcat作为Http服务,也可以用Undertow来代替。Undertow在高并发业务场景中,性能优于Tomcat。所以,如果我们的系统是高并发请求,不妨使用一下Undertow,你会发现你的系统性能会得到很大的提升。

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

(0)

相关推荐

  • Spring Boot如何使用Undertow代替Tomcat

    1. Undertow 简介 Undertow 是一个采用 Java 开发的灵活的高性能 Web 服务器,提供包括阻塞和基于 NIO 的非堵塞机制.Undertow 是红帽公司的开源产品,是 Wildfly 默认的 Web 服务器.Undertow 提供一个基础的架构用来构建 Web 服务器,这是一个完全为嵌入式设计的项目,提供易用的构建器 API,完全向下兼容 Java EE Servlet 3.1 和低级非堵塞的处理器. 2. Undertow特点 高性能 在多款同类产品的压测中,在高并发情

  • Spring Boot实现Undertow服务器同时支持HTTP2、HTTPS的方法

    前言 如今,企业级应用程序的高性能安全加密的常见场景是同时支持HTTP和HTTPS两种协议,这篇文章考虑如何让Spring Boot应用程序同时支持HTTP和HTTPS两种协议.Spring Boot的web容器已经有容器可以支持HTTP2了,这个例子中选择了Undertow高性能服务器作为Spring Boot的web容器. What-什么是HTTP2 HTTP2是HTTP协议自1999年HTTP1.1发布后的首个更新,主要基于SPDY协议.由互联网工程任务组(IETF)的 Hypertext

  • 使用 Spring Boot 内嵌容器 Undertow创建服务器的方法

    Undertow是一个Web服务器,那么它就需要具备的现代Web服务器的基本特性,比如Servlet,JSP,文件服务器,代理服务器,安全认证等.undertow目前已经实现了绝大多数功能,并且因为wildfly通过了JavaEE7 TCK认证,所以可以说Undertow是一个通过Servlet 3.1认证的Web服务器和容器.这篇文章只分析Undertow的主干流程上的主要功能,即undertow-core和undertow-servlet. 1.简介 Undertow是一个非常轻量并高性能的

  • 记一次springboot中用undertow的坑

    目录 springboot中用undertow的坑 本文实验的环境如下 环境准备 使用springboot2.2.11.springboot2.2.12.springboot2.2.13 如果是生产采用了上述几个版本的sringboot springboot需放弃Tomcat,选择Undertow吗? SpringBoot中的Tomcat容器 SpringBoot设置Undertow Tomcat与Undertow的优劣对比 springboot中用undertow的坑 场景:准备基于sprin

  • 关于idea中SpringBoot启动失败的坑

    很多时候你新建了Maven 或者SpringBoot 工程,激动的点了主启动类,你就发现了下面的错误 这里说的是啥意思呢,你没有数据库相关的链接,数据库相关的链接在哪里配置呢,就是在你的Resource文件目录下的properties 或者yml文件中 但是这里你可能会说,我**不用数据库,我干啥配这个b玩意,我想说这句话的时候,你已经点了很多遍的主启动都报这个错误, 今天你算来对了,我敢肯定80%的人都遇到过这个问题.但是不知道为啥,今天我给你分析一下昂: ①:在IDEA 中用SpringIn

  • SpringBoot 定时任务遇到的坑

    前言 springboot已经支持了定时任务Schedule模块,一般情况已经完全能够满足我们的实际需求.今天就记录一下我使用 schedule 时候踩的坑吧. 想要使用定时,我们首先要开启支持,其实就是在启动类上面加个注解就 Ok. @SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(A

  • springboot中用fastjson处理返回值为null的属性值

    我们先来看代码: @Configuration public class WebMvcConfig extends WebMvcConfigurationSupport { public FastJsonHttpMessageConverter fastJsonHttpMessageConverter() { FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter()

  • 记一次springboot服务凌晨无故宕机问题的解决

    表述 在一次服务更新后发现每天凌晨0点3秒服务准时挂,开始的时候认为是maven依赖中存在system.exit(3)类似这样的代码,但是我想了下这个代码很多客户都有用到但是只有这一个客户出现了问题,而且另外一个服务没有更新在此前几个月都是没问题的 这几天也是一样无故挂了. 环境 windows服务器 排查 1.初步怀疑是内存泄漏问题,在启动脚本中加入 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\heapdump.log,第二天起来一看

  • idea使用spring Initializr 快速搭建springboot项目遇到的坑

    前言: 以前用习惯了sts,今天尝试使用IDEA 搭建springboot项目工程,却遇到了个小坑.不知道你们是否遇到过,分享如下: 首先我的maven使用的是3.5.3 首先创建springboot: 使用的是默认spring官网的镜像.这里改动不大. 选了个web. 项目创建成功 在启动类右键,没有run方法 在pom.xml上右键,将其添加为maven项目 然后发现Test模块报错. 查看pom.xml文件,发现2.3.5Release版本变红,怀疑是版本不对应问题. 创建时发现没有2.3

  • SpringBoot整合OpenFeign的坑

    目录 项目集成OpenFegin 集成OpenFegin依赖 实现远程调用 解决问题 问题描述 问题分析 问题解决 最近,在使用SpringBoot+K8S开发微服务系统,既然使用了K8S,我就不想使用SpringCloud了.为啥,因为K8S本身的就提供了非常6的服务注册与发现.限流.熔断.负载均衡等等微服务需要使用的技术,那我为啥还要接入SpringCloud呢?额,说了这么多,在真正使用SpringBoot+K8S这一套技术栈的时候,也会遇到一些问题,比如我不需要使用SpringCloud

  • 基于SpringBoot项目遇到的坑--Date入参问题

    目录 SpringBoot Date入参问题 1.传输中的Date类型时间不准确 2.后台返回的json数据 springboot接口入参的一些问题 入参绑定 入参错误全局异常处理 SpringBoot Date入参问题 springboot项目遇到的坑-----使用@ResponseBody @RequestBody,对象Date 类型入参,返回json格式化 1.传输中的Date类型时间不准确 时区会有8个小时偏差 原因分析 而SpringBoot默认的是Jackson框架转换,而Jacks

  • springBoot整合RocketMQ及坑的示例代码

    版本: JDK:1.8 springBoot:1.5.10 rocketMQ:4.2.0 pom 配置: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> </parent> <d

  • 基于springboot 配置文件context-path的坑

    目录 配置文件context-path的坑 context-path配置失效问题 配置文件context-path的坑 context-path: /manage 这个配置加入后会导致访问spring的页面都需要加这个/manage前缀,这个配置的作用是区分与spring重名的页面 context-path配置失效问题 springboot升级到2.0版本后 server.context-path就升级成了server.servlet.context-path:"/url" 以上为个人

随机推荐