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

max-http-header-size引起的oom是什么情況,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

創(chuàng)新互聯(lián)致力于互聯(lián)網(wǎng)網(wǎng)站建設(shè)與網(wǎng)站營(yíng)銷,提供網(wǎng)站制作、成都網(wǎng)站建設(shè)、網(wǎng)站開(kāi)發(fā)、seo優(yōu)化、網(wǎng)站排名、互聯(lián)網(wǎng)營(yíng)銷、成都小程序開(kāi)發(fā)、公眾號(hào)商城、等建站開(kāi)發(fā),創(chuàng)新互聯(lián)網(wǎng)站建設(shè)策劃專家,為不同類型的客戶提供良好的互聯(lián)網(wǎng)應(yīng)用定制解決方案,幫助客戶在新的全球化互聯(lián)網(wǎng)環(huán)境中保持優(yōu)勢(shì)。

記一次線上OOM事故

根據(jù)用戶反饋,某服務(wù)不能提供服務(wù),然后我們進(jìn)行排查,進(jìn)程id還在,但日志不輸出。通過(guò)jstat -gcutil 查看內(nèi)存使用情況;發(fā)現(xiàn)出現(xiàn)Full GC了。

查看內(nèi)存使用情況
ps -ef | grep --color=auto 項(xiàng)目名 | grep --color=auto -v "grep" | awk '{print $2}' | xargs -i jstat -gcutil {} 2000

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

S0:幸存1區(qū)當(dāng)前使用比例
S1:幸存2區(qū)當(dāng)前使用比例
E:伊甸園區(qū)使用比例
O:老年代使用比例
M:元數(shù)據(jù)區(qū)使用比例
CCS:壓縮使用比例
YGC:年輕代垃圾回收次數(shù)
FGC:老年代垃圾回收次數(shù)
FGCT:老年代垃圾回收消耗時(shí)間
GCT:垃圾回收消耗總時(shí)間

當(dāng)年輕代內(nèi)存滿時(shí),會(huì)引發(fā)一次普通GC,該GC僅回收年輕代。需要強(qiáng)調(diào)的時(shí),年輕代滿是指Eden代滿,Survivor滿不會(huì)引發(fā)GC

當(dāng)年老代滿時(shí)會(huì)引發(fā)Full GC,F(xiàn)ull GC將會(huì)同時(shí)回收年輕代、年老代

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

一看就有問(wèn)題了。

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

查看Histogram

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

進(jìn)行引用查看

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

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

通過(guò)mat分析查看這個(gè)對(duì)象內(nèi)存占用很大有10M左右,所以重點(diǎn)對(duì)這個(gè)類分析,看看干了什么。

org.apache.coyote.Response#outputBuffer這個(gè)類是tomcat輸出到socket時(shí)的類。

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

問(wèn)題就在這里了,這里的對(duì)象內(nèi)存10m左右?。?!

這個(gè)值怎么來(lái)的呢?老同事設(shè)置的,也不知道當(dāng)初為啥設(shè)置這個(gè)值。這個(gè)原因后面給出

server:
  max-http-header-size: 10000000

源碼分析,后方高能!查看tomcat調(diào)用鏈路

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

org.apache.catalina.connector.CoyoteAdapter#service max-http-header-size引起的oom是什么情況

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

max-http-header-size引起的oom是什么情況 最后tomcat通過(guò)socket返回結(jié)果

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());
            }
        }
    }

也就是一個(gè)請(qǐng)求會(huì)返回10m數(shù)據(jù)給前端,在用jemter100個(gè)并發(fā)測(cè)試時(shí),堆內(nèi)存直接打滿。服務(wù)停止。

為什么會(huì)設(shè)置這個(gè)值 max-http-header-size呢?

由于項(xiàng)目提供的api接口提供給第三方平臺(tái)使用,用戶身份校驗(yàn)是放在header里來(lái)做的。當(dāng)?shù)谌狡脚_(tái)沒(méi)按著規(guī)范來(lái)傳值呢?系統(tǒng)發(fā)生錯(cuò)誤。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 {
              	 // 這行代碼報(bào)錯(cuò)
                if (!inputBuffer.parseRequestLine(keptAlive)) {
                    if (inputBuffer.getParsingRequestLinePhase() == -1) {
                        return SocketState.UPGRADING;
                    } else if (handleIncompleteRequestLineRead()) {
                        break;
                    }
                }

               .....
            } catch (IOException e) {
                if (log.isDebugEnabled()) {
                    // 打印錯(cuò)誤。。。。。。
                    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 報(bào)錯(cuò)地方

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

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

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

org.apache.coyote.http11.Http11InputBuffer#init max-http-header-size引起的oom是什么情況

報(bào)錯(cuò)原因在于,SocketChannel.read的數(shù)據(jù)大于接受的buffer了。默認(rèn)buffer的是16kb,如果超出則報(bào)錯(cuò)。而tomcat遇到這個(gè)錯(cuò)誤時(shí)并沒(méi)有拋出該異常,而是記錄日志;并輸出結(jié)果是code=400;

而老同事通過(guò)排查日志發(fā)現(xiàn)Error parsing HTTP request header 百度搜索后,果斷調(diào)整max-http-header-size。當(dāng)把max-http-header-size調(diào)整10m時(shí),第三方平臺(tái)調(diào)用接口正常并返回驗(yàn)證失敗錯(cuò)誤;第三方平臺(tái)發(fā)現(xiàn)后跳轉(zhuǎn)驗(yàn)證規(guī)則后并未反饋該情況給老同事;則為oom埋下深坑;

關(guān)于max-http-header-size引起的oom是什么情況問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

文章標(biāo)題:max-http-header-size引起的oom是什么情況
文章源于:http://muchs.cn/article28/pdggcp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁(yè)設(shè)計(jì)公司響應(yīng)式網(wǎng)站、虛擬主機(jī)App開(kāi)發(fā)、微信小程序、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)