文档章节

Tomcat调优之maxHttpHeaderSize设置

十七宝宝
 十七宝宝
发布于 2017/05/31 16:27
字数 1221
阅读 215
收藏 0
点赞 0
评论 0

系统中要批量修改N多辆车的车队归属,Request Header无法承载,因此项目中报错:

[http-nio-8081-exec-6] org.apache.coyote.http11.Http11Processor.service Error parsing HTTP request header

Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.

java.lang.IllegalArgumentException: Request header is too large

at org.apache.coyote.http11.Http11InputBuffer.fill(Http11InputBuffer.java:735)

at org.apache.coyote.http11.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:497)

at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:667)

at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)

at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802)

at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1410)

at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)

at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

at java.lang.Thread.run(Thread.java:745)

 

查看对应的类代码,其中涉及的方法如下:

public SocketState process(SocketWrapper<S> socketWrapper) throws IOException { RequestInfo rp = request.getRequestProcessor(); rp.setStage(org.apache.coyote.Constants.STAGE_PARSE); // Setting up the I/O setSocketWrapper(socketWrapper); getInputBuffer().init(socketWrapper, endpoint); getOutputBuffer().init(socketWrapper, endpoint); // Flags keepAlive = true; comet = false; openSocket = false; sendfileInProgress = false; readComplete = true; if (endpoint.getUsePolling()) { keptAlive = false; } else { keptAlive = socketWrapper.isKeptAlive(); } if (disableKeepAlive()) { socketWrapper.setKeepAliveLeft(0); } while (!getErrorState().isError() && keepAlive && !comet && !isAsync() && httpUpgradeHandler == null && !endpoint.isPaused()) { // Parsing the request header try { setRequestLineReadTimeout(); if (!getInputBuffer().parseRequestLine(keptAlive)) { if (handleIncompleteRequestLineRead()) { break; } } if (endpoint.isPaused()) { // 503 - Service unavailable response.setStatus(503); setErrorState(ErrorState.CLOSE_CLEAN, null); } else { keptAlive = true; // Set this every time in case limit has been changed via JMX request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount()); // Currently only NIO will ever return false here if (!getInputBuffer().parseHeaders()) { // We've read part of the request, don't recycle it // instead associate it with the socket openSocket = true; readComplete = false; break; } if (!disableUploadTimeout) { setSocketTimeout(connectionUploadTimeout); } } } catch (IOException e) { if (getLog().isDebugEnabled()) { getLog().debug( sm.getString("http11processor.header.parse"), e); } setErrorState(ErrorState.CLOSE_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: getLog().info(message); break; case DEBUG: getLog().debug(message); } } // 400 - Bad Request response.setStatus(400); setErrorState(ErrorState.CLOSE_CLEAN, t); getAdapter().log(request, response, 0); } if (!getErrorState().isError()) { // Setting up filters, and parse some request headers rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE); try { prepareRequest(); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); if (getLog().isDebugEnabled()) { getLog().debug(sm.getString( "http11processor.request.prepare"), t); } // 500 - Internal Server Error response.setStatus(500); setErrorState(ErrorState.CLOSE_CLEAN, t); getAdapter().log(request, response, 0); } } if (maxKeepAliveRequests == 1) { keepAlive = false; } else if (maxKeepAliveRequests > 0 && socketWrapper.decrementKeepAlive() <= 0) { keepAlive = false; } // Process the request in the adapter if (!getErrorState().isError()) { try { rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE); getAdapter().service(request, response); // Handle when the response was committed before a serious // error occurred. Throwing a ServletException should both // set the status to 500 and set the errorException. // If we fail here, then the response is likely already // committed, so we can't try and set headers. if(keepAlive && !getErrorState().isError() && ( response.getErrorException() != null || (!isAsync() && statusDropsConnection(response.getStatus())))) { setErrorState(ErrorState.CLOSE_CLEAN, null); } setCometTimeouts(socketWrapper); } catch (InterruptedIOException e) { setErrorState(ErrorState.CLOSE_NOW, e); } catch (HeadersTooLargeException e) { // The response should not have been committed but check it // anyway to be safe if (response.isCommitted()) { setErrorState(ErrorState.CLOSE_NOW, e); } else { response.reset(); response.setStatus(500); setErrorState(ErrorState.CLOSE_CLEAN, e); response.setHeader("Connection", "close"); // TODO: Remove } } catch (Throwable t) { ExceptionUtils.handleThrowable(t); getLog().error(sm.getString( "http11processor.request.process"), t); // 500 - Internal Server Error response.setStatus(500); setErrorState(ErrorState.CLOSE_CLEAN, t); getAdapter().log(request, response, 0); } } // Finish the handling of the request rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT); if (!isAsync() && !comet) { if (getErrorState().isError()) { // If we know we are closing the connection, don't drain // input. This way uploading a 100GB file doesn't tie up the // thread if the servlet has rejected it. getInputBuffer().setSwallowInput(false); } else if (expectation && (response.getStatus() < 200 || response.getStatus() > 299)) { // Client sent Expect: 100-continue but received a // non-2xx final response. Disable keep-alive (if enabled) // to ensure that the connection is closed. Some clients may // still send the body, some may send the next request. // No way to differentiate, so close the connection to // force the client to send the next request. getInputBuffer().setSwallowInput(false); keepAlive = false; } endRequest(); } rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT); // If there was an error, make sure the request is counted as // and error, and update the statistics counter if (getErrorState().isError()) { response.setStatus(500); } request.updateCounters(); if (!isAsync() && !comet || getErrorState().isError()) { if (getErrorState().isIoAllowed()) { getInputBuffer().nextRequest(); getOutputBuffer().nextRequest(); } } if (!disableUploadTimeout) { if(endpoint.getSoTimeout() > 0) { setSocketTimeout(endpoint.getSoTimeout()); } else { setSocketTimeout(0); } } rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE); if (breakKeepAliveLoop(socketWrapper)) { break; } } rp.setStage(org.apache.coyote.Constants.STAGE_ENDED); if (getErrorState().isError() || endpoint.isPaused()) { return SocketState.CLOSED; } else if (isAsync() || comet) { return SocketState.LONG; } else if (isUpgrade()) { return SocketState.UPGRADING; } else { if (sendfileInProgress) { return SocketState.SENDFILE; } else { if (openSocket) { if (readComplete) { return SocketState.OPEN; } else { return SocketState.LONG; } } else { return SocketState.CLOSED; } } } }

而报错的地方则是在:

// Currently only NIO will ever return false here if (!getInputBuffer().parseHeaders()) { // We've read part of the request, don't recycle it // instead associate it with the socket openSocket = true; readComplete = false; break; } if (!disableUploadTimeout) { setSocketTimeout(connectionUploadTimeout); } 的时候抛出了异常,对应的catch块代码如下: 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: getLog().info(message); break; case DEBUG: getLog().debug(message); } } // 400 - Bad Request response.setStatus(400); setErrorState(ErrorState.CLOSE_CLEAN, t); getAdapter().log(request, response, 0); }

错误日志的输出,是配置在LocalStrings.properties中的,相关的两个属性:

http11processor.fallToDebug=\n Note\: further occurrences of HTTP header parsing errors will be logged at DEBUG level. http11processor.header.parse=Error parsing HTTP request header

找到对应的 getInputBuffer().parseHeaders()

public boolean parseHeaders() throws IOException { if (!parsingHeader) { throw new IllegalStateException( sm.getString("iib.parseheaders.ise.error")); } HeaderParseStatus status = HeaderParseStatus.HAVE_MORE_HEADERS; do { status = parseHeader(); // Checking that // (1) Headers plus request line size does not exceed its limit // (2) There are enough bytes to avoid expanding the buffer when // reading body // Technically, (2) is technical limitation, (1) is logical // limitation to enforce the meaning of headerBufferSize // From the way how buf is allocated and how blank lines are being // read, it should be enough to check (1) only. if (pos > headerBufferSize || buf.length - pos < socketReadBufferSize) { throw new IllegalArgumentException( sm.getString("iib.requestheadertoolarge.error")); } } while ( status == HeaderParseStatus.HAVE_MORE_HEADERS ); if (status == HeaderParseStatus.DONE) { parsingHeader = false; end = pos; return true; } else { return false; } }

可知此处涉及了两个缓冲区大小,headerBufferSize和socketReadBufferSize,如果读取时数据的长度大于这两个值,就会报iib.requestheadertoolarge.error即Request header is too large,在网上搜索时,有的是因为这个设置导致的400,解决方法就是修改Tomcat的server.xml, 在<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />的配置中增加maxHttpHeaderSize的配置

在org.apache.coyote.http11.AbstractHttp11Protocol类中定义了其默认值:

/** Maximum size of the HTTP message header. */ private int maxHttpHeaderSize = 8 * 1024; /** Maximum size of the post which will be saved when processing certain requests, such as a POST. */ private int maxSavePostSize = 4 * 1024; /** * Specifies a different (usually longer) connection timeout during data upload. */ private int connectionUploadTimeout = 300000; /** Maximum size of trailing headers in bytes */ private int maxTrailerSize = 8192; /** Maximum size of extension information in chunked encoding */ private int maxExtensionSize = 8192; /**Maximum amount of request body to swallow.*/ private int maxSwallowSize = 2 * 1024 * 1024;

 

修改Tomcat的server.xml:

<Connector port="8080" protocol="HTTP/1.1"

connectionTimeout="20000"

redirectPort="8443" URIEncoding="UTF-8" maxHttpHeaderSize="1024000"/>

maxHttpHeaderSize修改为合理的大小

注意请求须为POST请求。

© 著作权归作者所有

共有 人打赏支持
十七宝宝
粉丝 0
博文 12
码字总数 6864
作品 0
杭州
程序员
tomcat7自身调优和JVM调优

Tomcat优化其实就是对server.xml优化(开户线程池,调整http connector参数) 搜索【<Executor name="tomcatThreadPool"】,开启并调整为 <Executor name="tomcatThreadPool" namePrefix="ca......

蜡笔小小小新
2015/09/07
128
1
tomcat 高流量调优

java 环境配置:export JAVA_OPTS="-server -Xms8g -Xmx8g -Xss128k -XX:ParallelGCThreads=20-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:SurvivorRatio=8-XX:TargetSurvivorRatio=90 -......

千惊万喜
2016/12/09
26
0
Tomcat安全优化

开启用户登录失败锁定 路径: /opt/java/tomcat/conf/server.xml 当前值: 加固建议: 检查项: 限制远程管理IP 路径: /opt/java/tomcat/conf/server.xml 当前值: 加固建议: 增加 检查项: 禁止显...

一条特立独行的贪吃蛇
01/06
0
0
WebLogic设置一个参数的大小(在tomcat中是maxHttpHeaderSize)

项目在tomcat服务器中运行需要设置服务器的一个参数 ,是在server.xml文件中的maxHttpHeaderSize参数。 换到WebLogic服务器中,在WebLogic服务器没找到这个参数,该如何设置那?...

D-li
2015/04/10
5.5K
1
SolrCloud的Java客户端请求体过大导致的400错误

由于业务原因,Solr客户端发起的查询请求体数据太多,默认采用get方式超过 tomcat maxHttpHeaderSize。 方案: 增加 tomcat maxHttpHeaderSize 到32k,默认8k 修改solr客户端默认提交方式pos...

从前
2014/12/06
0
0
基于APR模式的Tomcat环境部署

1、版本信息 Tomcat的通讯模型总共为3种,分别为BIO、NIO、APR,而本次所采用的模式为APR。 3种模式的区别: 2、基础安装 # vim /etc/profile # vim /opt/tomcat/conf/server.xml # vim /op...

workming
2015/11/05
0
0
jsp乱码问题

jsp乱码一直是一个困扰我的问题,今天经过百度找到了比较有效的解决方式,总结如下: 第一步:配置编码过滤器,在doFilter()中设置request.setCharacterEncoding("UTF-8");这种过滤一般只是对...

学习的小猪
2014/03/26
0
0
jmeter 及测试

负载测试:在一定的工作负荷下,给系统造成的负荷及系统响应的时间。 压力测试:在一定的负荷条件下,长时间连续运行系统给系统性能造成的影响。 1.性能测试(Performance Test):通常收集所...

kenzheng
2015/12/21
24
0
at org.apache.coyote.http11.AbstractOutputBuffer.checkLengthBeforeWrite

tomcat报错: [2015-08-24 14:56:41] 3084386 ERROR - com.tools.common.util.close.CloseUtil - Unable to close org.apache.catalina.connector.CoyoteWriter@39c3e691 org.apache.coyote.......

余二五
2017/11/07
0
0
Slow HTTP Denial of Service Attack

整改建议   1.中断使用URL不支持HTTP方法访问的会话   2.限制HTTP头及包长至一个合理数值   3.设置一个绝对的会话超时时间   4.服务器支持backlog的情况下,需设置一个合理的大小  ...

疯子阳
2015/10/13
610
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

mysql 主从复制中遇到的错误!

。。。。。

万建宁
10分钟前
0
0
DUBBO 详细介绍

摘要: 主要核心部件: Remoting: 网络通信框架,实现了 sync-over-async 和 request-response 消息机制. RPC: 一个远程过程调用的抽象,支持负载均衡、容灾和集群功能 Registry: 服务目录框架...

明理萝
20分钟前
0
1
4 个快速的 Python 编译器 for 2018

简评:Python 和其他的解释型语言一样经常被吐槽性能不行,所以开发人员为了提升性能创建了不少编译器,本文则选取其中的四个做了基准测试。 Python 其实是一种相当快的语言,但它并不像编译...

极光推送
24分钟前
0
0
spring boot注册多个MQ服务器的问题

关于注册到多个MQ源的文章已经有很多了,这里记录一下声明queue的坑; 如果使用注册bean的方式声明queue,会导致声明的queue同时被注册到所有的MQ源上; //如果使用下面的声明方式,que...

placeholder
25分钟前
0
0
Java面试基础篇——第九篇:BIO,NIO,AIO的区别

现在IO模型主要分三类:BIO(同步阻塞IO),NIO(同步非阻塞IO),AIO()。 先来看看BIO。 1. BIO 服务端接受到请求后,要指派或新建一个线程去处理客户端的IO请求,直到收到断开连接的指令。这么做...

developlee的潇洒人生
30分钟前
0
0
@RequestMapping @ResponseBody 和 @RequestBody 用法与区别

1.@RequestMapping 国际惯例先介绍什么是@RequestMapping,@RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为...

特拉仔
32分钟前
1
0
基于 HTML5 结合互联网+ 的 3D 隧道

前言 目前,物资采购和人力成本是隧道业发展的两大瓶颈。比如依靠民间借贷,融资成本很高;采购价格不透明,没有增值税发票;还有项目管控和供应链管理的问题。成本在不断上升,利润在不断下...

xhload3d
34分钟前
0
0
济南小程序热度分析

原文链接:http://www.jnqianle.cn/company/2072.html

tianma3798
35分钟前
1
0
大数据软件

beats 采集 kafka spark hive es grafana zeppelin

ArlenXu
37分钟前
0
0
Mac item2常用快捷键

标签 新建标签:command + t 关闭标签:command + w 切换标签:command + 数字 command + 左右方向键 切换全屏:command + enter 查找:command + f 分屏 水平分屏:command + d 垂直分屏:c...

说回答
40分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部