昨天开会在讨论项目的时候有个同事对tomcat发表的一番评论,特别是他的并发量最多200的言论,使我觉得我有必要在这里把tomcat的基本调优参数重新说明一下,以免有些初学者被他误导。
首先,最早的web服务器是Rob McColl在伊利诺斯大学的NCSA里面开发的,直到1995年的最新版本才将之称为Apache,即“A PAtChy Web Sever”,在1999年,Apache的创始人员成立了ASF,而tomcat则是有ASF资助开发的,tomcat工程源于早期的Java servlet技术,由Sun公司最早创建,而在此期间,ASF也推出了JServ产品(第一个Servlet引擎与Apache Web服务器的整合)。也是在1999年,Sun将Servlet的代码赠予了ASF,从tomcat的第一个版本tomcat3.x开始,就可以清晰的看到servlet与Jserd的完美整合。
说了一下tomcat的历史,现在我们回到正题,说说tomcat调优所要用到的一些常用的参数,在列出参数之前,我在看能在日志里面看到如下的信息:tomcat freezes or pauses with no requests being processed,outofmemory exceptions等等,更具自己的需要进行调试。
jvm: 无论是SUN还是IBM的JVM里面的参数都是一样的,-Xms<size>(jvm初始大小)-Xmx<size>(jvm最大值),在Linux(windows)上通过修改<TOMCAT_HOME>/catalina.sh(catalina.bat)里面,在起始位置添加JAVA_OPTS="$JAVA_OPTS -Xms512m -Xmx1024m"(SET JAVA_OPTS="%JAVA_OPT% -Xms512m -Xmx1024m"),现在已经容器的初始值为512m,最大值1024m。但是在SUN和IBM对怎样设置持有不同的解释,SUN建议-Xms和-Xmx设置相同的值,这样有助于提高GC的预测能力,有助于更快的启动;而IBM认为最好有个区分,这样有助于容器被更好更有效的利用,所以我个人建议,根据你使用的jdk来设置,如果你想了解内存的使用情况还是在开始的地方添加JAVA_OPTS="$JAVA_OPTS -verbose:gc"(SET JAVA_OPTS="%JAVA_OPT% -verbose:gc")在无负载的时候你可以看到[GC 108696K->98522K(154488K), 0.0034733 secs],其中108696K为垃圾收集之前的Java内存大小,98522K为垃圾收集之后Java使用的内存大小,154488K表示Java的可用空间大小。除此之外,IBM还提供了-Xmine设置扩展的最小值、-Xmaxe设置扩展的最大值、-Xminf执行GC后释放的最小比、-Xmaxf执行GC后释放的最大比;SUN还提供了 -XX:MaxPermSize 用以指定持久产生堆的大小。
server.xml: maxThreads 可用线程的最大数值。它是指定的并发上限,默认值200(这就是我那个同事并发量200的根据)
maxSpareThreads tomcat允许的空闲线程最大值
minSpareThreads tomcat允许的空闲线程最小值
tcpNoDeplay 当设为true时,启用TCP_NO_DEPLAY网络套接口选项,用以减少网络传送的包的数量,但是可能导致交互型客户端服务器响应时间加长
maxKeepAliveRequest 控制http请求的keep-alive行为,启用持久性的连接,用以指定连接被服务器关闭之前放入队列的最大数目,默认100
socketBuffer 以字节为单位设置缓冲区大小,默认9000字节,若设为-1挤关闭缓冲区
enableLookups 设为false会禁用API调用DNS查询操作request.getRemoteHost(),这样会减少查询所花时间,从而提高性能
acceptCount 当所有请求处理线程都被占用时,允许接收连接请求队列的最大长度,默认10,最大值由系统决定
address 该属性用以绑定IP地址
compressibleMimeTypes 该属性为常用http压缩列表,以逗号隔开,默认值text/html,text/xml,text/plain
maxHttpHeaderSize 请求响应最大长度,默认4096(4k)
maxPostSize 容器出来post的最大程度,默认2097152(2M)
除去默认的Http Connector之外,tomcat还提供另外两个高性能的连接器:APR和NIO。其中APR是特定于平台的二进制库,需要下载相关包,我还没有在实践中使用过,也不知道怎么进行配置,而NIO是在jdk1.4之后才被引入的,使用了不同于标准的“面向流”Java I/O实现方法,通过分配一个固定的线程池来解决入栈连接问题,虽然会由于连接数目的增加性能呈现下降趋势,但是由于其请求线程会阻塞其他线程,直到获得客户端响应,因此响应时间相对较短。
现在给出一个最基本的配置:
<Connector port="8080" protocol="org.apache.coyote.http11.http11NioProtocol" maxThreads="150" connectionTimeout="20000" redirectPort="8443" acceptorThreadCount="2" socket.directBuffer="false"/>
这个和默认的Http Connector的结构差不多,下面说说相关属性的含义:
acceptorThreadCount 用于接受连接的线程数目,默认值为1,由cpu决定数量
pollerThreadCount 用于运行选择事件的线程数目,默认值为1
selectorTimeout 选择器select()系统调用的超时时间值,单位毫秒,建议不要太大
socket.directBuffer 设为true使用直接的字节缓冲,为false表示字节缓冲影射的Java
socket.rxBuffSize 以字节为单位的套接字接受缓冲区大小,默认值25188
socket.txBuffSize 以字节为单位的套接字发送缓冲区大小,默认值43800
socket.appReadBufSiz tomcat中打开的每个连接都与一个读字节缓冲区相关联,默认8192,当并发量小的时候可以增加用以缓冲更大的数据
socket.appWriteBufSiz tomcat中打开的每个连接都与一个写字节缓冲区相关联,默认8192,当并发量小的时候可以增加用以缓冲更大的数据
socket.bufferPool 为减少垃圾收集操作,NIO连接器用以缓存部分对象,默认值500
socket.bufferPoolSize NioChannel池大小,以字节为单位,默认值100M
socket.keycache tomcat缓存与建相关的对象来减少垃圾收集,默认值500
socket.eventcache tomcat缓存选择器时间对象来减少垃圾收集,默认值500
socket.tcpNoDeplay 同标准的tcpNoDeplay属性相同,默认为false
socket.soKeepAlive 套接字持久连接设置,默认false
selectorPool.maxSelectors 池中可以使用的选择器的最大数目,默认200
selectorPool.maxSpareSelectors 池中空闲选择器的最大数,默认值-1
如果希望每一个线程都使用一个选择器则在启动脚本里面添加CATANLINA_OPTS="-Dorg.apache.tomcat.util.net.NioSelectorShared=false",默认为true
当然除了这些以外,还要在web.xml里面对jsp进行设置,
development tomcat检查jsp页面修改情况,默认值true
reloading tomcat后台编译功能,每隔一段时间检查和编译jsp页面,默认为true
checkInterval 若reloading为true,checkInterval参数定期触发编译的频率,默认值300s
modificationTestInterval jsp文件修改情况的触发频率,默认4s
genStringAsCharArray 设为true可以产生效率较高的字符数组
enablePooling 是否启用标签分类池,默认true
trimSpace 是否从响应中移去无用的空格,默认false
当然除了上面提到的这些,肯定还有其他的参数设置,而这些只是我用到的,如果写错了什么地方,请各位多多指教,要是有什么不明白的,可以与我联系,谢谢
首先,最早的web服务器是Rob McColl在伊利诺斯大学的NCSA里面开发的,直到1995年的最新版本才将之称为Apache,即“A PAtChy Web Sever”,在1999年,Apache的创始人员成立了ASF,而tomcat则是有ASF资助开发的,tomcat工程源于早期的Java servlet技术,由Sun公司最早创建,而在此期间,ASF也推出了JServ产品(第一个Servlet引擎与Apache Web服务器的整合)。也是在1999年,Sun将Servlet的代码赠予了ASF,从tomcat的第一个版本tomcat3.x开始,就可以清晰的看到servlet与Jserd的完美整合。
说了一下tomcat的历史,现在我们回到正题,说说tomcat调优所要用到的一些常用的参数,在列出参数之前,我在看能在日志里面看到如下的信息:tomcat freezes or pauses with no requests being processed,outofmemory exceptions等等,更具自己的需要进行调试。
jvm: 无论是SUN还是IBM的JVM里面的参数都是一样的,-Xms<size>(jvm初始大小)-Xmx<size>(jvm最大值),在Linux(windows)上通过修改<TOMCAT_HOME>/catalina.sh(catalina.bat)里面,在起始位置添加JAVA_OPTS="$JAVA_OPTS -Xms512m -Xmx1024m"(SET JAVA_OPTS="%JAVA_OPT% -Xms512m -Xmx1024m"),现在已经容器的初始值为512m,最大值1024m。但是在SUN和IBM对怎样设置持有不同的解释,SUN建议-Xms和-Xmx设置相同的值,这样有助于提高GC的预测能力,有助于更快的启动;而IBM认为最好有个区分,这样有助于容器被更好更有效的利用,所以我个人建议,根据你使用的jdk来设置,如果你想了解内存的使用情况还是在开始的地方添加JAVA_OPTS="$JAVA_OPTS -verbose:gc"(SET JAVA_OPTS="%JAVA_OPT% -verbose:gc")在无负载的时候你可以看到[GC 108696K->98522K(154488K), 0.0034733 secs],其中108696K为垃圾收集之前的Java内存大小,98522K为垃圾收集之后Java使用的内存大小,154488K表示Java的可用空间大小。除此之外,IBM还提供了-Xmine设置扩展的最小值、-Xmaxe设置扩展的最大值、-Xminf执行GC后释放的最小比、-Xmaxf执行GC后释放的最大比;SUN还提供了 -XX:MaxPermSize 用以指定持久产生堆的大小。
server.xml: maxThreads 可用线程的最大数值。它是指定的并发上限,默认值200(这就是我那个同事并发量200的根据)
maxSpareThreads tomcat允许的空闲线程最大值
minSpareThreads tomcat允许的空闲线程最小值
tcpNoDeplay 当设为true时,启用TCP_NO_DEPLAY网络套接口选项,用以减少网络传送的包的数量,但是可能导致交互型客户端服务器响应时间加长
maxKeepAliveRequest 控制http请求的keep-alive行为,启用持久性的连接,用以指定连接被服务器关闭之前放入队列的最大数目,默认100
socketBuffer 以字节为单位设置缓冲区大小,默认9000字节,若设为-1挤关闭缓冲区
enableLookups 设为false会禁用API调用DNS查询操作request.getRemoteHost(),这样会减少查询所花时间,从而提高性能
acceptCount 当所有请求处理线程都被占用时,允许接收连接请求队列的最大长度,默认10,最大值由系统决定
address 该属性用以绑定IP地址
compressibleMimeTypes 该属性为常用http压缩列表,以逗号隔开,默认值text/html,text/xml,text/plain
maxHttpHeaderSize 请求响应最大长度,默认4096(4k)
maxPostSize 容器出来post的最大程度,默认2097152(2M)
除去默认的Http Connector之外,tomcat还提供另外两个高性能的连接器:APR和NIO。其中APR是特定于平台的二进制库,需要下载相关包,我还没有在实践中使用过,也不知道怎么进行配置,而NIO是在jdk1.4之后才被引入的,使用了不同于标准的“面向流”Java I/O实现方法,通过分配一个固定的线程池来解决入栈连接问题,虽然会由于连接数目的增加性能呈现下降趋势,但是由于其请求线程会阻塞其他线程,直到获得客户端响应,因此响应时间相对较短。
现在给出一个最基本的配置:
<Connector port="8080" protocol="org.apache.coyote.http11.http11NioProtocol" maxThreads="150" connectionTimeout="20000" redirectPort="8443" acceptorThreadCount="2" socket.directBuffer="false"/>
这个和默认的Http Connector的结构差不多,下面说说相关属性的含义:
acceptorThreadCount 用于接受连接的线程数目,默认值为1,由cpu决定数量
pollerThreadCount 用于运行选择事件的线程数目,默认值为1
selectorTimeout 选择器select()系统调用的超时时间值,单位毫秒,建议不要太大
socket.directBuffer 设为true使用直接的字节缓冲,为false表示字节缓冲影射的Java
socket.rxBuffSize 以字节为单位的套接字接受缓冲区大小,默认值25188
socket.txBuffSize 以字节为单位的套接字发送缓冲区大小,默认值43800
socket.appReadBufSiz tomcat中打开的每个连接都与一个读字节缓冲区相关联,默认8192,当并发量小的时候可以增加用以缓冲更大的数据
socket.appWriteBufSiz tomcat中打开的每个连接都与一个写字节缓冲区相关联,默认8192,当并发量小的时候可以增加用以缓冲更大的数据
socket.bufferPool 为减少垃圾收集操作,NIO连接器用以缓存部分对象,默认值500
socket.bufferPoolSize NioChannel池大小,以字节为单位,默认值100M
socket.keycache tomcat缓存与建相关的对象来减少垃圾收集,默认值500
socket.eventcache tomcat缓存选择器时间对象来减少垃圾收集,默认值500
socket.tcpNoDeplay 同标准的tcpNoDeplay属性相同,默认为false
socket.soKeepAlive 套接字持久连接设置,默认false
selectorPool.maxSelectors 池中可以使用的选择器的最大数目,默认200
selectorPool.maxSpareSelectors 池中空闲选择器的最大数,默认值-1
如果希望每一个线程都使用一个选择器则在启动脚本里面添加CATANLINA_OPTS="-Dorg.apache.tomcat.util.net.NioSelectorShared=false",默认为true
当然除了这些以外,还要在web.xml里面对jsp进行设置,
development tomcat检查jsp页面修改情况,默认值true
reloading tomcat后台编译功能,每隔一段时间检查和编译jsp页面,默认为true
checkInterval 若reloading为true,checkInterval参数定期触发编译的频率,默认值300s
modificationTestInterval jsp文件修改情况的触发频率,默认4s
genStringAsCharArray 设为true可以产生效率较高的字符数组
enablePooling 是否启用标签分类池,默认true
trimSpace 是否从响应中移去无用的空格,默认false
当然除了上面提到的这些,肯定还有其他的参数设置,而这些只是我用到的,如果写错了什么地方,请各位多多指教,要是有什么不明白的,可以与我联系,谢谢