Spring Boot中的max-http-header-size配置方式

 更新时间:2022年09月30日 10:28:09   作者:融极  
这篇文章主要介绍了Spring Boot中的max-http-header-size配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

关于max-http-header-size配置 

概述

默认情况下,Spring Boot Web 应用程序包括一个预配置的嵌入式 Web 服务器。但是,在某些情况下,我们希望修改默认配置以满足自定义要求。

在本教程中,讲解如何在 Spring Boot 2.x 应用程序的application.properties文件中对请求标头进行设置和使用max-http-header-size属性。

Max-HTTP-Header-Size

Spring Boot 支持Tomcat、Undertow和Jetty作为嵌入式服务器。通常,我们在 Spring Boot 应用程序中的application.properties文件或application.yaml文件中进行服务器配置。

大多数 Web 服务器都有自己的一组 HTTP 请求header大小限制。HTTP header值受服务器实现的限制。在 Spring Boot 应用程序中,最大 HTTP header大小是使用server.max-http-header-size 配置的。Tomcat和Jetty的实际默认值为8kB,Undertow的默认值为1MB。

要修改最大 HTTP header大小,在application.properties文件中进行如下配置:

server.max-http-header-size=1024000

从 Spring Boot 2.1 开始,可使用DataSize可解析值:

server.max-http-header-size=10KB

请求头太大

假设发送的请求的总 HTTP header大小大于max-http-header-size值。服务器以“400 Bad request”错误拒绝请求。在下一个示例中,我们将在日志文件中看到此错误。

让我们创建一个控制器,它有一个名为 token 的header属性:

@RestController
@RequestMapping(value = "/request-header-test")
public class MaxHttpHeaderSizeController {
    @GetMapping
    public boolean testMaxHTTPHeaderSize(@RequestHeader(value = "token") String token) {
    return true;
    }
}

接下来,让我们向application.properties文件添加一些属性:

## Server connections configuration
server.tomcat.threads.max=200
server.connection-timeout=5s
server.max-http-header-size=8KB
server.tomcat.max-swallow-size=2MB
server.tomcat.max-http-post-size=2MB

当我们在token中传递一个大小大于 8kb的字符串值时,得到 400 错误,如下所示:

max-http-header-size配置不合理导致OOM问题排查

#线上max-http-header-size导致oom问题排查

1. 首先线上vm参数配置-XX:+HeapDumpOnOutOfMemoryError

线上oom后会生成java_pidxxx.hprof文件

2. 使用Jprofiler分析下占用最大的空间是 char[]数组

3. 看下OOM栈信息

// 这里把栈信息粘贴出来看一下
Thread dump at 27588:02.814.491
* Thread group "main":
  Thread "http-nio-51026-exec-115":
    at java.lang.OutOfMemoryError.<init>() (line: 48)
    at java.nio.HeapByteBuffer.<init>(int, int) (line: 57)
    at java.nio.ByteBuffer.allocate(int) (line: 335)
    at org.apache.coyote.http11.Http11OutputBuffer.<init>(org.apache.coyote.Response, int) (line: 110)
    at org.apache.coyote.http11.Http11Processor.<init>(org.apache.coyote.http11.AbstractHttp11Protocol, org.apache.coyote.Adapter) (line: 163)
    at org.apache.coyote.http11.AbstractHttp11Protocol.createProcessor() (line: 1001)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(org.apache.tomcat.util.net.SocketWrapperBase, org.apache.tomcat.util.net.SocketEvent) (line: 853)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun() (line: 1590)
    at org.apache.tomcat.util.net.SocketProcessorBase.run() (line: 49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) (line: 1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run() (line: 624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run() (line: 61)
    at java.lang.Thread.run() (line: 748)

4. 定位源码

可以看到多半就是分配headerBufferSize导致的了

5. 查看char[]里面具体内容

不难发现数组后面大部分元素都是0

6. 综合上述情况,可以得出一下结论

  • OOM是因为分配请求头太大导致的
  • 分配的char[]数组大部分空间都未使用到

7. 为什么会分配那么大的请求头?是否和某个配置相关吗?

排查配置发现

server:
    max-http-header-size: 10485760 #10M,值太大,并发量一上来服务就内存溢出了
# max-http-header-size单位为字节,默认值为8*1024字节=8kb

修改配置前和修改后再次压测,修改后发现不会有这种情况了。

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

相关文章

  • Java计算两个汉字相似度的实现方法

    Java计算两个汉字相似度的实现方法

    有时候我们希望计算两个汉字的相似度,比如文本的 OCR 等场景,用于识别纠正,本文给大家详细介绍了Java计算两个汉字相似度的实现方法,文中有详细的实现代码,需要的朋友可以参考下
    2023-11-11
  • spring boot使用自定义的线程池执行Async任务

    spring boot使用自定义的线程池执行Async任务

    这篇文章主要介绍了spring boot使用自定义的线程池执行Async任务的相关资料,需要的朋友可以参考下
    2018-02-02
  • C/C++和Java的交互详解

    C/C++和Java的交互详解

    本文旨在简单的介绍一下如何让java层和C/C++层相互调用,这里主要是使用了JNI技术,并没有深究其原理,只是做了个实现,其目的是为后面的学习打开一扇窗。
    2016-01-01
  • Spring bean对象实例化实现过程图解

    Spring bean对象实例化实现过程图解

    这篇文章主要介绍了Spring bean对象实例化实现过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Spring boot定时任务的原理及动态创建详解

    Spring boot定时任务的原理及动态创建详解

    这篇文章主要给大家介绍了关于Spring boot定时任务的原理及动态创建的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  •  Spring 中 Bean 的生命周期详解

     Spring 中 Bean 的生命周期详解

    这篇文章主要介绍了Spring中Bean的生命周期详解,Java中的公共类称之为Bean或Java Bean,而Spring中的Bean指的是将对象的生命周期
    2022-09-09
  • Java实现单链表基础操作

    Java实现单链表基础操作

    大家好,本篇文章主要讲的是Java实现单链表基础操作,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • Java8中新判空方法之Optional类的使用详解

    Java8中新判空方法之Optional类的使用详解

    Opitonal类就是Java提供的为了解决大家平时判断对象是否为空用的。本文将通过示例为大家讲解一下Optional类的使用,感兴趣的可以收藏一下
    2022-12-12
  • Java8中方便又实用的Map函数总结

    Java8中方便又实用的Map函数总结

    java8之后,常用的Map接口中添加了一些非常实用的函数,可以大大简化一些特定场景的代码编写,提升代码可读性,快跟随小编一起来看看吧
    2022-11-11
  • 基于Java制作一个好玩的打飞机游戏

    基于Java制作一个好玩的打飞机游戏

    这篇文章主要介绍了基于Java制作的打飞机小游戏,这里整理了详细的代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01

最新评论