千家信息网

max-http-header-size引起的oom是什么情况

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,max-http-header-size引起的oom是什么情况,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。记一次线上OOM事故根据
千家信息网最后更新 2026年11月02日max-http-header-size引起的oom是什么情况

max-http-header-size引起的oom是什么情况,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

记一次线上OOM事故

根据用户反馈,某服务不能提供服务,然后我们进行排查,进程id还在,但日志不输出。通过jstat -gcutil 查看内存使用情况;发现出现Full GC了。

查看内存使用情况
ps -ef | grep --color=auto 项目名 | grep --color=auto -v "grep" | awk '{print $2}' | xargs -i jstat -gcutil {} 2000

S0:幸存1区当前使用比例S1:幸存2区当前使用比例E:伊甸园区使用比例O:老年代使用比例M:元数据区使用比例CCS:压缩使用比例YGC:年轻代垃圾回收次数FGC:老年代垃圾回收次数FGCT:老年代垃圾回收消耗时间GCT:垃圾回收消耗总时间

当年轻代内存满时,会引发一次普通GC,该GC仅回收年轻代。需要强调的时,年轻代满是指Eden代满,Survivor满不会引发GC

当年老代满时会引发Full GC,Full GC将会同时回收年轻代、年老代

生成堆的dump文件
jmap -dump:format=b,file=812.hprof 15968
打包文件
tar -czf 814.tar.gz 814.hprof
MAT分析内存

一看就有问题了。

查看Histogram

进行引用查看

通过mat分析查看这个对象内存占用很大有10M左右,所以重点对这个类分析,看看干了什么。

org.apache.coyote.Response#outputBuffer这个类是tomcat输出到socket时的类。

问题就在这里了,这里的对象内存10m左右!!!

这个值怎么来的呢?老同事设置的,也不知道当初为啥设置这个值。这个原因后面给出

server:  max-http-header-size: 10000000

源码分析,后方高能!查看tomcat调用链路

org.apache.catalina.connector.CoyoteAdapter#service

最后tomcat通过socket返回结果

org.apache.coyote.http11.Http11OutputBuffer#commit

 protected void commit() throws IOException {        response.setCommitted(true);        if (headerBuffer.position() > 0) {            // Sending the response header buffer            headerBuffer.flip();            try {                socketWrapper.write(isBlocking(), headerBuffer);            } finally {                headerBuffer.position(0).limit(headerBuffer.capacity());            }        }    }

也就是一个请求会返回10m数据给前端,在用jemter100个并发测试时,堆内存直接打满。服务停止。

为什么会设置这个值 max-http-header-size呢?

由于项目提供的api接口提供给第三方平台使用,用户身份校验是放在header里来做的。当第三方平台没按着规范来传值呢?系统发生错误。Error parsing HTTP request header

org.apache.coyote.http11.Http11Processor#service

public SocketState service(SocketWrapperBase socketWrapper)        throws IOException {        RequestInfo rp = request.getRequestProcessor();        rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);        // Setting up the I/O        setSocketWrapper(socketWrapper);        inputBuffer.init(socketWrapper);        outputBuffer.init(socketWrapper);        // Flags        keepAlive = true;        openSocket = false;        readComplete = true;        boolean keptAlive = false;        SendfileState sendfileState = SendfileState.DONE;        while (!getErrorState().isError() && keepAlive && !isAsync() && upgradeToken == null &&                sendfileState == SendfileState.DONE && !endpoint.isPaused()) {            // Parsing the request header            try {                   // 这行代码报错                if (!inputBuffer.parseRequestLine(keptAlive)) {                    if (inputBuffer.getParsingRequestLinePhase() == -1) {                        return SocketState.UPGRADING;                    } else if (handleIncompleteRequestLineRead()) {                        break;                    }                }               .....            } catch (IOException e) {                if (log.isDebugEnabled()) {                    // 打印错误。。。。。。                    log.debug(sm.getString("http11processor.header.parse"), e);                }                setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);                break;            } catch (Throwable t) {                ExceptionUtils.handleThrowable(t);                UserDataHelper.Mode logMode = userDataHelper.getNextMode();                if (logMode != null) {                    String message = sm.getString("http11processor.header.parse");                    switch (logMode) {                        case INFO_THEN_DEBUG:                            message += sm.getString("http11processor.fallToDebug");                            //$FALL-THROUGH$                        case INFO:                            log.info(message, t);                            break;                        case DEBUG:                            log.debug(message, t);                    }                }                // 400 - Bad Request                response.setStatus(400);                setErrorState(ErrorState.CLOSE_CLEAN, t);                getAdapter().log(request, response, 0);            }         ......    }
org.apache.tomcat.util.net.NioChannel#read 报错地方

org.apache.tomcat.util.net.NioChannel#read

protected SocketChannel sc = null;@Override    public int read(ByteBuffer dst) throws IOException {        return sc.read(dst);    }

org.apache.coyote.http11.Http11InputBuffer#init

报错原因在于,SocketChannel.read的数据大于接受的buffer了。默认buffer的是16kb,如果超出则报错。而tomcat遇到这个错误时并没有抛出该异常,而是记录日志;并输出结果是code=400;

而老同事通过排查日志发现Error parsing HTTP request header 百度搜索后,果断调整max-http-header-size。当把max-http-header-size调整10m时,第三方平台调用接口正常并返回验证失败错误;第三方平台发现后跳转验证规则后并未反馈该情况给老同事;则为oom埋下深坑;

关于max-http-header-size引起的oom是什么情况问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

内存 比例 情况 年轻 问题 分析 垃圾 平台 第三方 错误 年代 数据 日志 老同事 服务 输出 原因 对象 接口 文件 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海睿民互联网科技有限公司 广州淘业互联网络科技 互联网科技公司的优势 互联网科技财经 互联网科技媒体 互联网科技论文 互联网科技美容 成都仁贤领冠互联网科技有限公司 汉立互联网科技有限公司联系电话 成都玖崟互联网科技有限公司乐商圈怎么样 互联网经济与金融科技 彤创互联网科技有限公司 互联网科技公司实习生 互联网5g黑科技有哪些 企晟互联网信息科技有限公司 用友工业互联网科技发展 工业互联网山东科技大学 山东有哪些互联网科技公司 易企秀互联网科技是做什么的 昆明中奇联合互联网科技 互联网科技活动banner 科技类互联网 广州互联网科技公司 互联网科技公司做什么 成都玖崟互联网科技有限公司乐商圈怎么样 中天科技中国工业互联网 福仕德教育科技互联网 科技互联网经济论坛 互联网金融金融科技 六子台科技互联网展会
0