最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot?max-http-header-size最大長度的那些事及JVM調(diào)優(yōu)方式

 更新時間:2022年09月30日 12:04:51   作者:菠蘿y  
這篇文章主要介紹了springboot?max-http-header-size最大長度的那些事及JVM調(diào)優(yōu)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

問題

線上程序出現(xiàn)了OOM,程序日志中的輸出為

Exception in thread "http-nio-8080-exec-1027" java.lang.OutOfMemoryError: Java heap space
Exception in thread "http-nio-8080-exec-1031" java.lang.OutOfMemoryError: Java heap space

看線程名稱應(yīng)該是tomcat的nio工作線程,線程在處理程序的時候因為無法在堆中分配更多內(nèi)存出現(xiàn)了OOM,幸好JVM啟動參數(shù)配置了-XX:+HeapDumpOnOutOfMemoryError,使用MAT打開拿到的hprof文件進行分析。

第一步就是打開Histogram看看占用內(nèi)存最大的是什么對象:

可以看到byte數(shù)組占用了接近JVM配置的最大堆的大小也就是8GB,顯然這是OOM的原因。

第二步看一下究竟是哪些byte數(shù)組,數(shù)組是啥內(nèi)容:

可以看到很明顯這和HTTP請求相關(guān),一個數(shù)組大概是10M的大小。

第三步通過查看GC根查看誰持有了數(shù)組的引用:

這符合之前的猜測,是tomcat的線程在處理過程中分配了10M的buffer在堆上。

至此,馬上可以想到一定是什么參數(shù)設(shè)置的不合理導(dǎo)致了這種情況,一般而言tomcat不可能為每一個請求分配如此大的buffer。

第四步就是檢查代碼里是否有tomcat或服務(wù)器相關(guān)配置,看到有這么一個配置:

max-http-header-size: 10000000

至此,基本已經(jīng)確定了八九不離十就是這個不合理的最大http請求頭參數(shù)導(dǎo)致的問題。

關(guān)于http header最大長度的那些事

http協(xié)議,超文本傳輸協(xié)議,HyperText Transfer Protocol,是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種網(wǎng)絡(luò)協(xié)議,所有的WWW文件都遵守這個標準。

關(guān)于http協(xié)議消息的格式,大家可以網(wǎng)上自行搜索,這里不再贅述。

本文關(guān)注的是其header部分,如下圖所示(紅框標注部分):

問題原型

有一個web application提供web service,這個web application基于java開發(fā),部署在tomcat容器上。

問題是:當客戶端發(fā)送一個GET請求,結(jié)果得到400的response,意思是說bad request。

檢查了這個request的代碼實現(xiàn)邏輯,并沒有相關(guān)input validation的邏輯,并且檢查server端日志發(fā)現(xiàn),request請求似乎并沒有到達我們自己代碼實現(xiàn)邏輯部分。這是為什么呢?

問題解釋

遇到這個問題時,第一步就是查看server端日志,但是覺得很tricky的是,最開始并沒有發(fā)現(xiàn)相關(guān)的日志,只是發(fā)現(xiàn)request并沒有到達我們自己代碼實現(xiàn)邏輯部分。

后來,mina同學眼神很好,發(fā)現(xiàn)了如下日志:

通過日志note信息發(fā)現(xiàn),該條日志在info級別下只會打印一次,之后都會是debug級別才打印,難怪之前沒有注意到這條日志。

從日志信息可知,request的header部分太大,超過了tomcat允許的最大值。

默認情況下,tomcat(8.0版本)允許的http請求header的最大值是8024個字節(jié)(8KB)。

那為什么之前沒有出現(xiàn)這個問題呢?

原因是,項目遷移到SCP平臺上之后,改成JWT token做權(quán)限校驗,這個JWT token會被添加到request的header,然而JWT token一般來說都很大(平均有6k個字節(jié)左右),所以說在增加了JWT token這個header以及其他一些相關(guān)的headers之后,整個request的header部分就超過8024個字節(jié),于是就出現(xiàn)了這個問題。

那么如何解決這個問題呢?可以從兩個方面考慮:

增加tomcat允許http header最大值。這個配置參數(shù)maxHttpHeaderSize可以設(shè)置tomcat允許的http header最大值。

減少header的size,比如不要添加無關(guān)的header到request。

擴展

在研究這個問題的過程中,其實還有一些其他疑問。首先,一個request的轉(zhuǎn)發(fā)流程大致如下:

那么,在這個流程中,為什么request在前面的部分沒有出現(xiàn)這個問題,而這個問題出現(xiàn)在最后一個技術(shù)棧是java/tomcat的component呢?

原因是,每個web服務(wù)器的http header最大長度的默認值不一樣,同時隨語言、版本不同也會不一樣。舉個例子tomcat 5的http header size的默認值是4K。

我找到了其他component中對于http header size的默認值的定義:

CF Router是用Go語言實現(xiàn),Go語言的http處理模塊對于它的定義是默認值1MB。

App Router是用Nodejs實現(xiàn),Nodejs的http處理模塊對它的定義是默認值80KB。

以上兩個默認值都要遠遠大于8KB,這也就解釋了沒什么問題出在最后一個component。

Tomcat修改maxParameterCount配置

問題

java.lang.IllegalStateException: More than the maximum number of request
 parameters (GET plus POST) for a single request ([10,000]) were detected.
  Any parameters beyond this limit have been ignored.
   To change this limit, set the maxParameterCount attribute
    on the Connector.

解決方案

以前使用外部Tomcat部署項目的時候,可以通過修改server.xml文件中的Connector節(jié)點maxParameterCount屬性值解決這個問題。

<Connector port=“8080” redirectPort=“8443” protocol=“HTTP/1.1” maxParameterCount="-1" />

因為SpringBoot使用的是內(nèi)嵌的Tomcat,無法配置server.xml。經(jīng)過查看相關(guān)API文檔并沒有發(fā)現(xiàn)可以直接在配置文件中配置maxParameterCount屬性,那么我們就在代碼中進行配置,在SpringBoot的API文檔中講解了通過實現(xiàn)WebServerFactoryCustomizer接口可以對Tomcat進行相關(guān)配置。

參考

自定義tomcat配置

創(chuàng)建一個類并實現(xiàn)WebServerFactoryCustomizer接口的customize方法。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

/**
 * 自定義Tomcat容器配置類
 *
 */
@Component
public class MyTomcatWebServerFactoryCustomizer 
        implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    public static final int DEFAULT_MAX_PARAMETER_COUNT = 10000;

    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 單次請求參數(shù)最大限制數(shù)
     */
    @Value("${server.tomcat.maxParameterCount}")
    private int maxParameterCount = DEFAULT_MAX_PARAMETER_COUNT;

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        if (logger.isDebugEnabled()) {
            logger.debug("MyTomcatWebServerFactoryCustomizer customize");
        }

        PropertyMapper propertyMapper = PropertyMapper.get();

        propertyMapper.from(this::getMaxParameterCount)
                .when((maxParameterCount) -> maxParameterCount != DEFAULT_MAX_PARAMETER_COUNT)
                .to((maxParameterCount) -> customizerMaxParameterCount(factory, maxParameterCount));
    }

    /**
     * 配置內(nèi)置Tomcat單次請求參數(shù)限制
     *
     * @param factory
     * @param maxParameterCount
     */
    private void customizerMaxParameterCount(TomcatServletWebServerFactory factory, 
                                             int maxParameterCount) {
        factory.addConnectorCustomizers(
                connector -> connector.setMaxParameterCount(maxParameterCount));
    }

    public void setMaxParameterCount(int maxParameterCount) {
        this.maxParameterCount = maxParameterCount;
    }

    public int getMaxParameterCount() {
        return maxParameterCount;
    }
}

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Springboot中登錄后關(guān)于cookie和session攔截問題的案例分析

    Springboot中登錄后關(guān)于cookie和session攔截問題的案例分析

    這篇文章主要介紹了Springboot中登錄后關(guān)于cookie和session攔截案例,本文通過實例圖文相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • java基于swing實現(xiàn)的連連看代碼

    java基于swing實現(xiàn)的連連看代碼

    這篇文章主要介紹了java基于swing實現(xiàn)的連連看代碼,包含了游戲中涉及的事件處理與邏輯功能,需要的朋友可以參考下
    2014-11-11
  • 在Spring Boot中使用swagger-bootstrap-ui的方法

    在Spring Boot中使用swagger-bootstrap-ui的方法

    這篇文章主要介紹了在Spring Boot中使用swagger-bootstrap-ui的方法,需要的朋友可以參考下
    2018-01-01
  • 解決springdataJPA對原生sql支持的問題

    解決springdataJPA對原生sql支持的問題

    這篇文章主要介紹了解決springdataJPA對原生sql支持的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • JAVA使用JDBC技術(shù)操作SqlServer數(shù)據(jù)庫實例代碼

    JAVA使用JDBC技術(shù)操作SqlServer數(shù)據(jù)庫實例代碼

    本篇文章主要介紹了JAVA使用JDBC技術(shù)操作SqlServer數(shù)據(jù)庫實例代碼,具有一定的參考價值,有興趣的可以了解一下。
    2017-01-01
  • idea撤銷git?commit操作詳解

    idea撤銷git?commit操作詳解

    這篇文章主要為大家介紹了idea撤銷git?commit操作詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • java控制Pdf自動打印的小例子

    java控制Pdf自動打印的小例子

    java控制Pdf自動打印的小例子,需要的朋友可以參考一下
    2013-04-04
  • 在Spring Boot中如何使用數(shù)據(jù)緩存

    在Spring Boot中如何使用數(shù)據(jù)緩存

    本篇文章主要介紹了在Spring Boot中如何使用數(shù)據(jù)緩存,具有一定的參考價值,有興趣的可以了解一下。
    2017-04-04
  • SpringBoot自定義Starter及使用

    SpringBoot自定義Starter及使用

    這篇文章主要介紹了SpringBoot自定義Starter及使用,Starter是Spring Boot中的一個非常重要的概念,Starter相當于模塊,它能將模塊所需的依賴整合起來并對模塊內(nèi)的Bean根據(jù)環(huán)境進行自動配置,需要的朋友可以參考下
    2023-07-07
  • 從零開始:快速入門SpringBoot注解的精髓

    從零開始:快速入門SpringBoot注解的精髓

    Spring?Boot是一個用于快速構(gòu)建基于Spring框架的應(yīng)用程序的開源框架,它通過使用注解來簡化配置和開發(fā)過程,使開發(fā)人員能夠更加專注于業(yè)務(wù)邏輯的實現(xiàn),Spring?Boot提供了許多注解,用于定義和配置應(yīng)用程序的各個方面,需要的朋友可以參考下
    2023-10-10

最新評論

博白县| 平塘县| 仁化县| 神农架林区| 万山特区| 诸城市| 台北县| 铜陵市| 仲巴县| 建德市| 原阳县| 重庆市| 泗洪县| 遂川县| 大渡口区| 门头沟区| 廉江市| 荔浦县| 临澧县| 永川市| 胶南市| 三门峡市| 梧州市| 涟水县| 南汇区| 梨树县| 绥滨县| 中超| 紫阳县| 康定县| 招远市| 怀安县| 子长县| 东兴市| 寿阳县| 庄浪县| 遂溪县| 西和县| 内乡县| 通辽市| 平武县|