精华内容
下载资源
问答
  • tomcat压力测试总结

    千次阅读 2019-06-13 10:30:58
    这段时间折腾了哈java web应用的压力测试,部署容器是tomcat 7。期间学到了蛮多散碎的知识点,及时梳理总结,构建良好且易理解的知识架构把它们组织起来,以备忘。 对web应用开发者来说,我们很关心应用可同时处理的...

    对tomcat来说,每一个进来的请求(request)都需要一个线程,直到该请求结束。

    这段时间折腾了哈java web应用的压力测试,部署容器是tomcat 7。期间学到了蛮多散碎的知识点,及时梳理总结,构建良好且易理解的知识架构把它们组织起来,以备忘。
    对web应用开发者来说,我们很关心应用可同时处理的请求数,以及响应时间。应用本身和它运行在其中的web容器是两个很重要的影响因素。
    对tomcat来说,每一个进来的请求(request)都需要一个线程,直到该请求结束。如果同时进来的请求多于当前可用的请求处理线程数,额外的线程就会被创建,直到到达配置的最大线程数(maxThreads属性值)。如果仍就同时接收到更多请求,这些来不及处理的请求就会在Connector创建的ServerSocket中堆积起来,直到到达最大的配置值(acceptCount属性值)。至此,任何再来的请求将会收到connection refused错误,直到有可用的资源来处理它们。

    分析、梳理、组织

    这里我们关心的是tomcat能同时处理的请求数和请求响应时间,显然Connector元素的maxThreads和acceptCount属性对其有直接的影响。无论acceptCount值为多少,maxThreads直接决定了实际可同时处理的请求数。而不管maxThreads如何,acceptCount则决定了有多少请求可等待处理。然而,不管是可立即处理请求还是需要放入等待区,都需要tomcat先接受该请求(即接受client的连接请求,建立socketchannel),那么tomcat同时可建立的连接数(maxConnections属性值)也会影响可同时处理的请求数。
    我们可把tomcat想象成一家医院,你来到医院大厅挂号看病,如果人家接受了,就相当于client和server建立socket连接了。接着你来到相应的科室,科室里每位医生都有一间诊室,这就相当于处理请求的线程;如果所有诊室都有病人,科室的调度护士会让你在科室小厅中耐心等待,直到他们通知你去几号诊室就诊;如果有空闲医生,你就可以立即就诊。
    有的病人到医院很仓促,结果轮到他挂号或者就诊了,他还在包里翻找病例本和医保卡,如果超过了护士或医生心里可承受的等待时间,他们就会让病人到旁边找去,先服务下位。这种情形跟Connector元素的connectionTimeout属性所起的作用很相像。如果当前连接器(Connector)在接受连接后,等待了指定的时间但仍未接收到requestURI line,就会抛出超时异常。

    知识点收集

    tomcat 7 的配置参考文档对相关属性已经描述的很详细了,这里把它们收集到一起:

    protocol

    Sets the protocol to handle incoming traffic. The default valueis HTTP/1.1 which uses an auto-switching mechanism to select either a blockingJava based connector or an APR/native based connector. If the PATH (Windows) orLD_LIBRARY_PATH (on most unix systems) environment variables contain the Tomcatnative library, the APR/native connector will be used. If the native librarycannot be found, the blocking Java based connector will be used. Note that theAPR/native connector has different settings for HTTPS than the Java connectors.
    To use an explicit protocol rather than rely on the auto-switching mechanismdescribed above, the following values may be used:
    org.apache.coyote.http11.Http11Protocol- blocking Java connector
    org.apache.coyote.http11.Http11NioProtocol- non blocking Java connector
    org.apache.coyote.http11.Http11AprProtocol- the APR/native connector.

    Custom implementations may also be used.
    Take a look at our Connector Comparison chart. The configuration for both Javaconnectors is identical, for http and https.
    For more information on the APR connector and APR specific SSL settings pleasevisit the APR documentation

    maxThreads

    The maximum number of request processing threads to be createdby this Connector, which therefore determines the maximum number ofsimultaneous requests that can be handled. If not specified, this attribute isset to 200. If an executor is associated with this connector, this attribute isignored as the connector will execute tasks using the executor rather than aninternal thread pool.

    acceptCount

    The maximum queue length for incoming connection requests whenall possible request processing threads are in use. Any requests received whenthe queue is full will be refused. The default value is 100.

    maxConnections

    The maximum number of connections that the server will acceptand process at any given time. When this number has beenreached, the server will accept, but not process, one further connection. Thisadditional connection be blocked until the number of connections beingprocessed falls below maxConnections at which point the server will startaccepting and processing new connections again. Note that once the limit hasbeen reached, the operating system may still accept connections based on theacceptCount setting. Thedefault value varies by connector type. For BIO the default is the value of maxThreads unless an Executor isused in which case the default will be the value of maxThreads from theexecutor. For NIO the default is 10000. For APR/native, the default is 8192.
    Note that for APR/native on Windows, the configured value will be reduced tothe highest multiple of 1024 that is less than or equal to maxConnections. Thisis done for performance reasons.
    If set to a value of -1, the maxConnections feature is disabled and connectionsare not counted.

    connectionTimeout

    The number of milliseconds this Connector will wait,after accepting a connection, for the request URI lineto be presented. Use a value of -1 to indicate no (i.e.infinite) timeout. The default value is 60000 (i.e. 60 seconds) but note thatthe standard server.xml that ships with Tomcat sets this to 20000 (i.e. 20seconds). Unless disableUploadTimeout is set to false, this timeout willalso be used when reading the request body (if any).

    进一步分析

    tomcat的http connector有三种:bio、nio、apr。从上面的属性描述中可以看出对于不同的connector实现,相同的属性可能会有不同的默认值和不同的处理策略,所以在调整配置前,要先弄清楚各种实现之间的不同,以及当前部署容器使用的是哪种connector。
    查阅Tomcat7 http connector 配置文档Connector Comparison部分便可获知各种connector实现间的差异。
    怎样才能知道容器使用的是何种connector实现?启动tomcat后,访问Server Status Page,看到如下信息即可知道使用的是何种connector:

    我的OS是windows,所以tomcat默认使用的是aprconnector。在linux上,默认使用的是bio connector。与nio相比,bio性能较低。将<TOMCAT_HOME>/conf/server.xml中的如下配置片段:

    <Connectorport="8080"protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />

    修改为:

    <Connectorport="8080"protocol="org.apache.coyote.http11.Http11NioProtocol"
                   connectionTimeout="20000"
                   redirectPort="8443" />

    就可将http connector切换至nio了。更多细节请参考修改Tomcat Connector运行模式,优化Tomcat运行性能

     

    官网说明:http://tomcat.apache.org/tomcat-7.0-doc/config/http.html

    一、最大线程数的设置

    Tomcat的server.xml中连接器设置如下

       <Connectorport="8080"  maxThreads="150"minSpareThreads="25" maxSpareThreads="75"  enableLookups="false"redirectPort="8443" acceptCount="100"  debug="0"connectionTimeout="20000"  disableUploadTimeout="true"/> 

     tomcat在配置时设置最大线程数,当前线程数超过这个数值时会出错,那么有没有办法捕获到这个错误,从而在client端显示出错信息?

     

    2. 如何加大tomcat连接数
    在tomcat配置文件server.xml中的<Connector />配置中,和连接数相关的参数有:
    minProcessors:最小空闲连接线程数,用于提高系统处理性能,默认值为10
    maxProcessors:最大连接线程数,即:并发处理的最大请求数,默认值为75
    acceptCount:允许的最大连接数,应大于等于maxProcessors,默认值为100
    enableLookups:是否反查域名,取值为:true或false。为了提高处理能力,应设置为false
    connectionTimeout:网络连接超时,单位:毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。
    其中和最大连接数相关的参数为maxProcessors和acceptCount。如果要加大并发连接数,应同时加大这两个参数。
    web server允许的最大连接数还受制于操作系统的内核参数设置,通常Windows是2000个左右,Linux是1000个左右。tomcat5中的配置示例:
        <Connector port="8080"
                  maxThreads="150" minSpareThreads="25"maxSpareThreads="75"
                  enableLookups="false" redirectPort="8443"acceptCount="100"
                  debug="0" connectionTimeout="20000" 
                  disableUploadTimeout="true" />
    对于其他端口的侦听配置,以此类推。

     

    3. tomcat中如何禁止列目录下的文件
    在{tomcat_home}/conf/web.xml中,把listings参数设置成false即可,如下:

    1.  <init-param>  

    2.  <param-name>listings</param-name>  

    3.  <param-value>false</param-value>  

    4.  </init-param>  

    4.如何加大tomcat可以使用的内存
    tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,需要调大。
    Unix下,在文件{tomcat_home}/bin/catalina.sh的前面,增加如下设置:
    JAVA_OPTS='-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】'
    需要把这个两个参数值调大。例如:
    JAVA_OPTS='-Xms256m -Xmx512m'
    表示初始化内存为256MB,可以使用的最大内存为512MB

    展开全文
  • 一.Tomcat内存优化 Tomcat内存优化主要是对 tomcat 启动参数优化,我们可以在 tomcat 的启动脚本 catalina.sh 中设置 java_OPTS 参数。 JAVA_OPTS参数说明 -server 启用jdk 的 server 版; -Xms java虚拟机初始...

    Tomcat有很多方面,我综合网上文章和自己的优化过程简单概括。

    一.Tomcat内存优化

      Tomcat内存优化主要是对 tomcat 启动参数优化,我们可以在 tomcat 的启动脚本 catalina.sh 中设置 java_OPTS 参数。 
      JAVA_OPTS参数说明 
      -server 启用jdk 的 server 版; 
      -Xms java虚拟机初始化时的最小内存; 
      -Xmx java虚拟机可使用的最大内存; 
      -XX: PermSize 内存永久保留区域 
      -XX:MaxPermSize 内存最大永久保留区域 
      服务器参数配置

      现公司服务器内存一般都可以加到最大2G ,所以可以采取以下配置:

      JAVA_OPTS=’-Xms1024m -Xmx2048m -XX: PermSize=256M -XX:MaxNewSize=256m -XX:MaxPermSize=256m’

      配置完成后可重启Tomcat ,通过以下命令进行查看配置是否生效: 
      首先查看Tomcat 进程号:

      sudo lsof -i:80

      我们可以看到Tomcat 进程号是 12222 。 
      查看是否配置生效:

      sudo jmap – heap 12222

      我们可以看到MaxHeapSize 等参数已经生效。

      **

    二.Tomcat并发优化

    **

      1.Tomcat连接相关参数

      在Tomcat 配置文件 server.xml 中的

      <Connector port="9027"
      protocol="HTTP/1.1"
      maxHttpHeaderSize="8192"
      minProcessors="100"
      maxProcessors="1000"
      acceptCount="1000"
      redirectPort="8443"
      disableUploadTimeout="true"/>

      2.调整连接器connector的并发处理能力

      1>参数说明

      maxThreads 客户请求最大线程数 (面试常问)
      minSpareThreads Tomcat初始化时创建的 socket 线程数 
      maxSpareThreads Tomcat连接器的最大空闲 socket 线程数 
      enableLookups 若设为true, 则支持域名解析,可把 ip 地址解析为主机名 
      redirectPort 在需要基于安全通道的场合,把客户请求转发到基于SSL 的 redirectPort 端口 
      acceptAccount 监听端口队列最大数,满了之后客户请求会被拒绝(不能小于maxSpareThreads ) 
      connectionTimeout 连接超时 
      minProcessors 服务器创建时的最小处理线程数 
      maxProcessors 服务器同时最大处理线程数 (面试常问)
      URIEncoding URL统一编码

      2>Tomcat中的配置示例

      <Connector port="9027"
      protocol="HTTP/1.1"
      maxHttpHeaderSize="8192"
      maxThreads="1000"
      minSpareThreads="100"
      maxSpareThreads="1000"
      minProcessors="100"
      maxProcessors="1000"
      enableLookups="false"
      URIEncoding="utf-8"
      acceptCount="1000"
      redirectPort="8443"
      disableUploadTimeout="true"/>

    3.Tomcat缓存优化

      1>参数说明

      c ompression 打开压缩功能 
      compressionMinSize 启用压缩的输出内容大小,这里面默认为2KB 
      compressableMimeType 压缩类型 

      connectionTimeout 定义建立客户连接超时的时间. 如果为 -1, 表示不限制建立客户连接的时间

      2>Tomcat中的配置示例

      <Connector port="9027"
      protocol="HTTP/1.1"
      maxHttpHeaderSize="8192"
      maxThreads="1000"
      minSpareThreads="100"
      maxSpareThreads="1000"
      minProcessors="100"
      maxProcessors="1000"
      enableLookups="false"
      compression="on"
      compressionMinSize="2048"
      compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
      connectionTimeout="20000"
      URIEncoding="utf-8"
      acceptCount="1000"
      redirectPort="8443"
      disableUploadTimeout="true"/>

      4.参考配置

      1>旧有的配置

      参考网络对服务器做过如下配置,拿出来分享下:

      <Connector port="9027"
      protocol="HTTP/1.1"
      maxHttpHeaderSize="8192"
      maxThreads="1000"
      minSpareThreads="25"
      maxSpareThreads="75"
      enableLookups="false"
      compression="on"
      compressionMinSize="2048"
      compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
      connectionTimeout="20000"
      URIEncoding="utf-8"
      acceptCount="200"
      redirectPort="8443"
      disableUploadTimeout="true" />
    

           后来发现在访问量达到3 百万多的时候出现性能瓶颈。 

    后来发现在访问量达到3 百万多的时候出现性能瓶颈。 
      2>更改后的配置

      <Connector port="9027"
      protocol="HTTP/1.1"
      maxHttpHeaderSize="8192"
      maxThreads="1000"
      minSpareThreads="100"
      maxSpareThreads="1000"
      minProcessors="100"
      maxProcessors="1000"
      enableLookups="false"
      compression="on"
      compressionMinSize="2048"
      compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
      connectionTimeout="20000"
      URIEncoding="utf-8"
      acceptCount="1000"
      redirectPort="8443"
      disableUploadTimeout="true"/>

      2>更改后的配置
      <Connector port="9027"
      protocol="HTTP/1.1"
      maxHttpHeaderSize="8192"
      maxThreads="1000"
      minSpareThreads="100"
      maxSpareThreads="1000"
      minProcessors="100"
      maxProcessors="1000"
      enableLookups="false"
      compression="on"
      compressionMinSize="2048"
      compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
      connectionTimeout="20000"
      URIEncoding="utf-8"
      acceptCount="1000"
      redirectPort="8443"
      disableUploadTimeout="true"/>

    压力性能测试

    Tomcat优化部分我们已经完成,接下来就需要比较一下优化前与优化后的性能对比。

            1.Jmeter

            Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。 它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器, 等等。JMeter 可以用于对服务器、网络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析整体性能。另外,JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。为了最大限度的灵活性,JMeter允许使用正则表达式创建断言。

            Apache jmeter 可以用于对静态的和动态的资源(文件,Servlet,Perl脚本,java 对象,数据库和查询,FTP服务器等等)的性能进行测试。它可以用于对服务器、网络或对象模拟繁重的负载来测试它们的强度或分析不同压力类型下的整体性能。你可以使用它做性能的图形分析或在大并发负载测试你的服务器/脚本/对象。云服务器、云数据库方案、网络安全防护优选

            Jmeter官网:http://jmeter.apache.org/

            1)JMeter的作用

           (1)能够对HTTP和FTP服务器进行压力和性能测试, 也可以对任何数据库进行同样的测试(通过JDBC),Jmeter支持以下服务器协议类型测试:

            • Web - HTTP, HTTPS

            • SOAP / REST

            • FTP

            • Database via JDBC

            • LDAP

            • Message-oriented middleware (MOM) via JMS

            • Mail - SMTP(S), POP3(S) and IMAP(S)

            • MongoDB (NoSQL)

            • Native commands or shell scripts

            • TCP

          (2)完全的可移植性和100% 纯java。

          (3)完全 Swing 和轻量组件支持(预编译的JAR使用 javax.swing.*)包。

          (4)完全多线程 框架允许通过多个线程并发取样和 通过单独的线程组对不同的功能同时取样。

          (5)精心的GUI设计允许快速操作和更精确的计时。

          (6)缓存和离线分析/回放测试结果。

            2)JMeter下载地址特性

          (1)可链接的取样器允许无限制的测试能力。

          (2)各种负载统计表和可链接的计时器可供选择。

          (3)数据分析和可视化插件提供了很好的可扩展性以及个性化。

          (4)具有提供动态输入到测试的功能(包括JavaScript)。

          (5)支持脚本编程的取样器(在1.9.2及以上版本支持BeanShell)。

            在设计阶段,JMeter能够充当HTTP PROXY(代理)来记录IE/NETSCAPE的HTTP请求,也可以记录apache等WebServer的log文件来重现HTTP流量。当这些HTTP客户端请求被记录以后,测试运行时可以方便的设置重复次数和并发度(线程数)来产生巨大的流量。JMeter还提供可视化组件以及报表工具把量服务器在不同压力下的性能展现出来。

            相比其他HTTP测试工具,JMeter最主要的特点在于扩展性强。JMeter能够自动扫描其lib/ext子目录下.jar文件中的插件,并且将其装载到内存,让用户通过不同的菜单调用。

            3)Jmeter使用

            使用Jmeter非常简单,windows下进入bin目录直接双击jmeter.bat文件即可,Linux下类似,需要运行jmeter.sh文件,Jmeter运行后显示以下界面:


             Jmeter使用起来比较简单,附件是一个简单的配置,直接导入即可使用。

            2.测试条件

            Tomcat版本:8.0.33

            测试项目:新创建一个web项目也不用实现任何代码,只需要部署即可以使用,只有一个index.jsp文件。

            JDK版本:jdk1.7.0.67

            请求方式:POST

            循环次数:100,1000

            线程数:10,100,1000

            总次数:总次数 = 线程数 * 循环次数

            CPU:英特尔 第二代酷睿 i5-2450M(双核)

            内存:8GB

            附件时Jmeter的配置文件,可以直接导入使用。

            3.测试结果

            从部分结果来看优化过的Tomcat会比默认性能及并发处理能力上有提高,但至于参数的配置需要结合硬件及操作系统来不断调整,所以并不会有一个万能的参数来使用,需要各位不断的测试不断更改。

            以下是一个简单的测试结果,循环100次,线程数分别为10,100,1000:

            各位估计已经发现了相同的应用下并不一定某种protocol就一定性能出色,因为Tomcat中的这个测试项目只有一个index.jsp页面,在较少线程数访问情况下BIO反应最快,而当线程数达到1000时NIO2性能最出色,而APR中规中矩,虽然这种测试的局限性很大,但也可以反映出:想要找出适合的配置及最佳性能需要结合实际,不断的测试与改进,最终才能达到一个相对稳定的性能,虽然此时的性能未必是最佳的,但却是能应对绝大多数情况的。

            总结:感谢网友的文章,此文多数来源于网友的解答。


    展开全文
  • Tomcat优化压力测试实例

    千次阅读 2011-07-04 16:31:49
    Tomcat和应用程序进行了压力测试后,如果您对应用程序的性能结果不太满意,就可以采取一些性能调整措施了,当然了前提是应用程序没有问题,我们这里 只讲Tomcat的调整。由于Tomcat的运行依赖于JVM,所以在这里...
    
    

    在 Tomcat和应用程序进行了压力测试后,如果您对应用程序的性能结果不太满意,就可以采取一些性能调整措施了,当然了前提是应用程序没有问题,

    我们这里 只讲Tomcat的调整。由于Tomcat的运行依赖于JVM,所以在这里我们把Tomcat的调整可以分为两类来详细描述:

    外部环境调整

      调整非Tomcat组件,例如Tomcat运行的操作系统和运行Tomcat的java虚拟机。

    自身调整

      修改Tomcat自身的参数,调整Tomcat配置文件中的参数。

    下面我们将详细讲解外部环境调整的有关内容,Tomcat自身调整的内容将在第2部分中阐述。

      1.JAVA虚拟机性能优化

      Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个java虚拟机。您可以选择自己的需要选择不同的操作系统和 对应的JDK的版本(只要是符合Sun发布的Java规范的),但我们推荐您使用Sun公司发布的JDK。确保您所使用的版本是最新的,因为Sun公司和 其它一些公司一直在为提高性能而对java虚拟机做一些升级改进。一些报告显示JDK1.4在性能上比JDK1.3提高了将近10%到20%。

      可以给Java虚拟机设置使用的内存,但是如果你的选择不对的话,虚拟机不会补偿。可通过命令行的方式改变虚拟机使用内存的大小。

     如下表所示有两个参数用来设置虚拟机使用内存的大小。 

       参数   描述

      -Xms<size> 
     JVM初始化堆的大小

     -Xmx<size> 
     JVM堆的最大值

    这两个值的大小一般根据需要进行设置。初始化堆的大小执行了虚拟机在启动时向系统申请的内存的大小。一般而言,这个参数不重要。但是有的应用程 序在大负载的情况下会急剧地占用更多的内存,此时这个参数就是显得非常重要,如果虚拟机启动时设置使用的内存比较小而在这种情况下有许多对象进行初始化, 虚拟机就必须重复地增加内存来满足使用。由于这种原因,我们一般把-Xms和-Xmx设为一样大,而堆的最大值受限于系统使用的物理内存。一般使用数据量 较大的应用程序会使用持久对象,内存使用有可能迅速地增长。当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃。因此一 般建议堆的最大值设置为可用内存的最大值的80%。

      Tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,需要调大。

      Windows下,在文件{tomcat_home}/bin/catalina.bat,Unix下,在文件{tomcat_home}/bin/catalina.sh的前面,增加如下设置:

      JAVA_OPTS='-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】'

      需要把这个两个参数值调大。例如:

      JAVA_OPTS='-Xms256m -Xmx512m'

      表示初始化内存为256MB,可以使用的最大内存为512MB。

      另外需要考虑的是Java提供的垃圾回收机制。虚拟机的堆大小决定了虚拟机花费在收集垃圾上的时间和频度。收集垃圾可以接受的速度与应用有关, 应该通过分析实际的垃圾收集的时间和频率来调整。如果堆的大小很大,那么完全垃圾收集就会很慢,但是频度会降低。如果你把堆的大小和内存的需要一致,完全 收集就很快,但是会更加频繁。调整堆大小的的目的是最小化垃圾收集的时间,以在特定的时间内最大化处理客户的请求。在基准测试的时候,为保证最好的性能, 要把堆的大小设大,保证垃圾收集不在整个基准测试的过程中出现。

      如果系统花费很多的时间收集垃圾,请减小堆大小。一次完全的垃圾收集应该不超过 3-5 秒。如果垃圾收集成为瓶颈,那么需要指定代的大小,检查垃圾收集的详细输出,研究 垃圾收集参数对性能的影响。一般说来,你应该使用物理内存的 80% 作为堆大小。当增加处理器时,记得增加内存,因为分配可以并行进行,而垃圾收集不是并行的。

    2.操作系统性能优化

      这里说的操作系统是指运行web服务器的系统软件,当然,不同的操作系统是为不同的目的而设计的。比如OpenBSD是面向安全的,因此在它的 内核中有许多的限制来防止不同形式的服务攻击(OpenBSD的一句座右铭是“默认是最安全的”)。这些限制或许更多地用来运行活跃的web服务器。

      而我们常用的Linux操作系统的目标是易用使用,因此它有着更高的限制。使用BSD内核的系统都带有一个名为“Generic”的内核,表明 所有的驱动器都静态地与之相连。这样就使系统易于使用,但是如果你要创建一个自定义的内核来加强其中某些限制,那就需要排除不需要的设备。Linux内核 中的许多驱动都是动态地加载的。但是换而言之,内存现在变得越来越便宜,所以因为加载额外的设备驱动就显得不是很重要的。重要的是要有更多的内存,并且在 服务器上腾出更多的可用内存。

      小提示:虽然现在内存已经相当的便宜,但还是尽量不要购买便宜的内存。那些有牌子的内存虽然是贵一点,但是从可靠性上来说,性价比会更高一些。

      如果是在Windows操作系统上使用Tomcat,那么最好选择服务器版本。因为在非服务器版本上,最终用户授权数或者操作系统本身所能承受的用户数、可用的网络连接数或其它方面的一些方面都是有限制的。并且基于安全性的考虑,必须经常给操作系统打上最新的补丁。

    3.Tomcat与其它web服务器整合使用

      虽然tomcat也可以作web服务器,但其处理静态html的速度比不上apache,且其作为web服务器的功能远不如apache,因此 我们想把apache和tomcat集成起来,将html与jsp的功能部分进行明确分工,让tomcat只处理jsp部分,其它的由apache, IIS等这些web服务器处理,由此大大节省了tomcat有限的工作“线程”。

     4.负载均衡

      在负载均衡的思路下,多台服务器为对称方式,每台服务器都具有同等的地位,可以单独对外提供服务而无须其他服务器的辅助。通过负载分担技术,将外部发送来的请求按一定规则分配到对称结构中的某一台服务器上,而接收到请求的服务器都独立回应客户机的请求。

      提供服务的一组服务器组成了一个应用服务器集群(cluster),并对外提供一个统一的地址。当一个服务请求被发至该集群时,根据一定规则选择一台服务器,并将服务转定向给该服务器承担,即将负载进行均衡分摊。

      通过应用负载均衡技术,使应用服务超过了一台服务器只能为有限用户提供服务的限制,可以利用多台服务器同时为大量用户提供服务。当某台服务器出 现故障时,负载均衡服务器会自动进行检测并停止将服务请求分发至该服务器,而由其他工作正常的服务器继续提供服务,从而保证了服务的可靠性。

      负载均衡实现的方式大概有四种:第一是通过DNS,但只能实现简单的轮流分配,不能处理故障,第二如果是基于MS IIS, Windows 2003 server本身就带了负载均衡服务,第三是硬件方式,通过交换机的功能或专门的负载均衡设备可以实现,第四种是软件方式,通过一台负载均衡服务器进行, 上面安装软件。使用Apache Httpd Server做负载平衡器,Tomcat集群节点使用Tomcat就可以做到以上第四种方式。这种方式比较灵活,成本相对也较低。另外一个很大的优点就是 可以根据应用的情况和服务器的情况采取一些策略。

    大家都知道,JAVA程序启动时都会JVM都会分配一个初始内存和最大内存给这个应用程序。这个初始内存和最大内存在一定程度都会影响程序的性能。比如说在应用程序用到最大内存的时候,JVM是要先去做垃圾回收的动作,释放被占用的一些内存。
            所以想调整Tomcat的启动时初始内存和最大内存就需要向JVM声明,一般的JAVA程序在运行都可以通过中-Xms -Xmx来调整应用程序的初始内存和最大内存:

     如:java -Xms64m -Xmx128m a.jar.
    tomcat的启动程序是包装过的,不能直接使用java -X..... tomcat.*来改变内存的设置。在Tomcat在改变这个设置
    有两种方法:
    1.    就需要在环境变量中加上TOMCAT_OPTS, CATALINA_OPTS两个属性,
            如 SET CATALINA_OPTS= -Xms64m -Xmx512m;
            ms是最小的,mx是最大,64m, 512m分别是指内存的容量.
    2.    修改Catalina.bat文件
           在166行“rem Execute Java with the applicable properties ”以下每行
    %_EXECJAVA% %JAVA_OPTS% %CATALINA_OPTS% %DEBUG_OPTS% -Djava.endorsed.dirs ="%JAVA_ENDORSED_DIRS%" -classpath "%CLASSPATH%" -Dcatalina.base="%CATALINA_BASE %" -Dcatalina.home="%CATALINA_HOME%" -Djava.io.tmpdir="%CATALINA_TMPDIR%" %MAINCLASS% %CMD_LINE_ARGS% %ACTION% 中的%CATALINA_OPTS% 替换成-Xms64m - Xmx512m


    Tomcat性能优化

    1.停用DNS查询
    server.xml里
    <Connector
    port="8887" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
    enableLookups="false" redirectPort="8443" acceptCount="100"
    debug="0" connectionTimeout="20000"
    disableUploadTimeout="true" />

    加上enableLookups="false";这样就不使用DNS查询,也不会有延迟了
    除非需要所有连接到服务器的HTTP客户端的完整主机名称

    注:Connector的enableLookups性属的意义是:调用request.getRemoteHost()是否会通过DNS查询来取得远处客户端的真正主机名称。true表示会查询,false表示以字符串格式传回客户端的IP地址。默认值是:true

    2,调整线程的数目
    Tomcat使用线程池以便对传入的请求提供快速的响应。
    通过更改Connector的minProcessors与maxProcessors的值,可以控制所分配的线程数目
    将这两个参数设为最佳值的最好方式是对各个参数尝试许多不同的设定值,然后以仿真的网络流量进行测试,同时并观察响应时间与内存的使用量。每一种机器、操 作系统与JVM的组合都可能有不同的表现,而且并非所有人的网站流量都会相同,所以没有现成的规则来决定最小与最大的线程数

    3.加快jsp的编译速度,预先编译jsp

    4.容量规划:经验式的容量规划,企业容量规划

    经验式的容量规划与企业容量规划最大的差异就是深度。经验式容量规划使用经验法则,因此比较像是经验预测,而企业容量规划则是深度地研究需求与性能,其目标是尽可能产生最精确的数字

    实战例子

    pache+tomcat+mysql

                Apache+Tomcat+Mysql网站配置
    前言:
    公司开发了一个网站,估计最高在线人数是3万,并发人数最多100人。开发的网站是否能否承受这个压力,如何确保网站的负荷没有问题,经过研究决定如下:
    (1) 采用负载平衡和集群技术,初步机构采用Apache+Tomcat的机群技术。
    (2) 采用压力测试工具,测试压力。工具是Loadrunner。
    硬件环境搭建:
    为了能够进行压力测试,需要搭建一个环境。刚开始时,测试在公司局域网内进行,但很快发现了一个问题,即一个脚本的压力测试结果每次都不一样,并且差别很大。原来是受公司网络的影响,于是决定搭建一个完全隔离的局域网测试。搭建后的局域网配置如下:
    (1) 网络速度:100M
    (2) 三台服务器:
    负载服务器 :操作系统windows2003,
    Tomcat服务器:操作系统windows2000 Professional
    数据库服务器:操作系统windows2000 Professional
    三台机器的cpu 2.4 G, 内存 1G。
    软件环境搭建:
    软件的版本如下:
    Apache 版本:2.054,
    Tomcat5.0.30,
    mysql :4.1.14.
    JDK1.5
    压力测试工具:Loadrunner7.8。
    负载平衡方案如下:
    一台机器(操作系统2003)安装apache,作为负载服务器,并安装tomcat作为一个worker;一个单独安装tomcat,作为第二个worker;剩下的一台单独作为数据库服务器。
        Apache和tomcat的负载平衡采用JK1.2.14(没有采用2.0,主要是2.0不再维护了)。
    集群方案:
         采用Tomcat本身的集群方案。在server.xml配置。
    压力测试问题:
    压力测试后,发现了一些问题,现一一列出来:
    (1)采用Tocmat集群后,速度变得很慢。因为集群后,要进行session复制,导致速度较慢。Tomcatd的复制,目前不支持 application 复制。复制的作用,主要用来容错的,即一台机器有故障后,apache可以把请求自动转发到另外一个机器。在容错和速度的考虑上,我们最终选择速度,去掉 了Tomcat集群。
    (2) 操作系统最大并发用户的限制:
    为了采用网站的压力,我们开始的时候,仅测试Tomcat的最大负载数。 Tomcat服务器安装的操作系统是windows2000 Professional。当我们用压力测试工具,并发测试时,发现只要超过15个并发用户,会经常出现无法连接服务器的情况。经过研究,发现是操作系统 的问题:windows2000 Professional 支持的并发访问用户有限,默认的好像是15个。于是我们把操作系统全部采用windows2003 server版本。
    (3) 数据库连接池的问题:
    测试数据库连接性能时,发现数据库连接速度很慢。每增加一些用户,连接性能就差了很多。我们采用的数据库连接池是DBCP,默认的初始化为50个,应该不 会很慢吧。查询数据库的连接数,发现初始化,只初始化一个连接。并发增加一个用户时,程序就会重新创建一个连接,导致连接很慢。原因就在这里了。如何解决 呢?偶尔在 JDK1.4下的Tomcat5.0.30下执行数据库连接压力测试,发现速度很快,程序创建数据库连接的速度也是很快的。看来JDK1.5的JDBC驱 动程序有问题。于是我们修改 JDK的版本为1.4.

    (4) C3P0和DBCP
    C3P0是Hibernate3.0默认的自带数据库连接池,DBCP是Apache开发的数据库连接池。我们对这两种连接池进行压力测试对比,发现在并发300个用户以下时,DBCP比C3P0平均时间快1秒左右。但在并发400个用户时,两者差不多。

    速度上虽然DBCP比C3P0快些,但是有BUG:当DBCP建立的数据库连接,因为某种原因断掉后,DBCP将不会再重新创建新的连接,导致必须重新启动Tomcat才能解决问题。DBCP的BUG使我们决定采用C3P0作为数据库连接池。
    调整后的方案:
    操作系统Windows2003 server版本
    JDK1.4
    Tomcat 5.0.30
    数据库连接池C3P0
    仅采用负载平衡,不采用集群。
    软件的配置:
    Apache配置:主要配置httpd.conf和新增加的文件workers.properties
    Httpd.conf:
    #一个连接的最大请求数量
    MaxKeepAliveRequests 10000 
    #NT环境,只能配置这个参数来提供性能
    <IfModule mpm_winnt.c> 
    #每个进程的线程数,最大1920。NT只启动父子两个进程,不能设置启动多个进程
    ThreadsPerChild 1900
    每个子进程能够处理的最大请求数
    MaxRequestsPerChild 10000
    </IfModule>

    # 加载mod_jk
    #
    LoadModule jk_module modules/mod_jk.so
    #
    # 配置mod_jk
    #
    JkWorkersFile conf/workers.properties
    JkLogFile logs/mod_jk.log
    JkLogLevel info
    #请求分发,对jsp文件,.do等动态请求交由tomcat处理
    DocumentRoot "C:/Apache/htdocs"
    JkMount /*.jsp loadbalancer
    JkMount /*.do loadbalancer
    JkMount /servlet/* loadbalancer
    #关掉主机Lookup,如果为on,很影响性能,可以有10多秒钟的延迟。
    HostnameLookups Off
    #缓存配置
    LoadModule cache_module modules/mod_cache.so
    LoadModule disk_cache_module modules/mod_disk_cache.so
    LoadModule mem_cache_module modules/mod_mem_cache.so

    <IfModule mod_cache.c>
    CacheForceCompletion 100
    CacheDefaultExpire 3600
    CacheMaxExpire 86400
    CacheLastModifiedFactor 0.1

    <IfModule mod_disk_cache.c>
    CacheEnable disk /
    CacheRoot c:/cacheroot
    CacheSize 327680
    CacheDirLength 4
    CacheDirLevels 5
    CacheGcInterval 4
    </IfModule>
    <IfModule mod_mem_cache.c>
    CacheEnable mem /
    MCacheSize 8192
    MCacheMaxObjectCount 10000
    MCacheMinObjectSize 1
    MCacheMaxObjectSize 51200
    </IfModule>
    </IfModule>
    worker. Properties文件
    #
    # workers.properties ,可以参考
    ::URL::http://jakarta.apache.org/tomcat/connectors-doc/config/workers.html
    # In Unix, we use forward slashes:
    ps=/

    # list the workers by name

    worker.list=tomcat1, tomcat2, loadbalancer

    # ------------------------
    # First tomcat server
    # ------------------------
    worker.tomcat1.port=8009
    worker.tomcat1.host=localhost
    worker.tomcat1.type=ajp13

    # Specify the size of the open connection cache.
    #worker.tomcat1.cachesize

    #
    # Specifies the load balance factor when used with
    # a load balancing worker.
    # Note:
    # ----> lbfactor must be > 0
    # ----> Low lbfactor means less work done by the worker.
    worker.tomcat1.lbfactor=900

    # ------------------------
    # Second tomcat server
    # ------------------------
    worker.tomcat1.port=8009
    worker.tomcat1.host=202.88.8.101
    worker.tomcat1.type=ajp13

    # Specify the size of the open connection cache.
    #worker.tomcat1.cachesize

    #
    # Specifies the load balance factor when used with
    # a load balancing worker.
    # Note:
    # ----> lbfactor must be > 0
    # ----> Low lbfactor means less work done by the worker.
    worker.tomcat1.lbfactor=2000

    # ------------------------
    # Load Balancer worker
    # ------------------------

    #
    # The loadbalancer (type lb) worker performs weighted round-robin
    # load balancing with sticky sessions.
    # Note:
    # ----> If a worker dies, the load balancer will check its state
    #        once in a while. Until then all work is redirected to peer
    #        worker.
    worker.loadbalancer.type=lb
    worker.loadbalancer.balanced_workers=tomcat1,tomcat2

    #
    # END workers.properties
    #

    Tomcat1配置:
    <!--配置server.xml
    去掉8080端口,即注释掉如下代码:-->
    <Connector 
    port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
                   enableLookups="false" redirectPort="8443" acceptCount="100"
                   debug="0" connectionTimeout="20000" 
                   disableUploadTimeout="true" />

    <!--配置8009端口如下:-->
    <Connector port="8009" 
    maxThreads="500" minSpareThreads="400" maxSpareThreads="450"
                   enableLookups="false" redirectPort="8443" debug="0"
                   protocol="AJP/1.3" />
    <!--配置引擎--> 
    <Engine name="Catalina" defaultHost="localhost" debug="0" jvmRoute="tomcat1">

    启动内存配置,开发configure tomcat程序即可配置:
    Initial memory pool: 200 M
    Maxinum memory pool:300M
    Tomcat2配置:
    配置和tomcat1差不多,需要改动的地方如下:
    <!--配置引擎--> 
    <Engine name="Catalina" defaultHost="localhost" debug="0" jvmRoute="tomcat2">

    启动内存配置,开发configure tomcat程序即可配置:
    Initial memory pool: 512 M
    Maxinum memory pool:768M
    Mysql配置:
    Server类型:Dedicated MySQL Server Machine 
    Database usage:Transational Database Only
    并发连接数量:Online Transaction Processing(OLTP)
    字符集:UTF8
    数据库连接池的配置:
    我们采用的是spring 框架,配置如下:
    <property name="hibernateProperties">
    <props>
    <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
    <prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
    <prop key="hibernate.connection.url">jdbc:mysql://202.88.1.103/db</prop>
    <prop key="hibernate.connection.username">sa</prop>
    <prop key="hibernate.connection.password"></prop>

    <prop key="hibernate.show_sql">false</prop>
    <prop key="hibernate.use_sql_comments">false</prop>

    <prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
    <prop key="hibernate.max_fetch_depth">2</prop>

    <prop key="hibernate.c3p0.max_size">200</prop>
    <prop key="hibernate.c3p0.min_size">5</prop>
    <prop key="hibernate.c3p0.timeout">12000</prop>
    <prop key="hibernate.c3p0.max_statements">50</prop>
    <prop key="hibernate.c3p0.acquire_increment">1</prop>
    </props>
    </property>
    其他的没有额外配置。
    LoadRunner 常见问题:
    (1)sofeware caused connction:这种情况,一般是脚本有问题,或者loadrunner有问题。解决方法:重新启动机器,或者重新录制脚本,估计是loadrunner的bug。
    (2)cannot connect to server:无法连接到服务器。这种情况是服务器的配置有问题,服务器无法承受过多的并发连接了。需要优化服务器的配置,
    如操作系统采用windows 2003 server,
    优化tomcat配置:maxThreads="500" minSpareThreads="400" maxSpareThreads="450"。但是tomcat 最多支持500个并发访问
    优化apache配置:
    ThreadsPerChild 1900
    MaxRequestsPerChild 10000
    其他的错误如:
    Action.c(10): Error -27791: Server has shut down the connection prematurely
    HTTP Status-Code=503 (Service Temporarily Unavailable)
    一般都是由于服务器配置不够好引起的,按照问题(2)处理,如果仍旧不行,需要优化硬件和调整程序了。
    Apache问题:
    (1) File does not exist: C:/Apache/htdocs/favicon.ico:
    这个问题是apache,htdocs目录没有favicon.ico文件引起的,该文件是网站的图标,仅在firefox,myIE等浏览器出现。
    (2) 图片无法显示:
    配置apache后,却无法显示图片。
    解决方法:把程序的图片,按照程序结构copy到apache的htdocs目录下。
    (3) 无法处理请求:
    当我们输入 ***.do 命令后,apache确返回错误信息,而连接tomcat却没有问题。原因是没有把.do命令转发给tomcat处理。解决方法如下:
    在apache配置文件中配置如下内容:
    DocumentRoot "C:/Apache/htdocs"
    JkMount /*.jsp loadbalancer
    JkMount /*.do loadbalancer


    总结:
    网站的压力测试,涉及的知识面挺广的,不仅要熟悉压力测试工具,还要知道如何配置和优化应用服务器和数据库,并且需要知道如何优化网络、操作系统、硬件系统。
    测试中不仅要善于发现问题,要知道如何解决。最重要的一点,要有良好的测试方法。刚开始测试时,可以从最简单的测试脚本入手,不需要太复杂的脚本,这样便 于发现问题。如我们刚开始时,就从一个简单的下载登陆界面的脚本入手,测试一个tomcat的压力负载。一个简单的获取登陆的脚本,帮助我们优化了 tomcat的配置;后来再测试数据库连接,也是一个简单的数据库连接脚本,帮助我们优化了数据库连接池;然后利用这些简单的脚本,测试apache的负 载平衡,优化了apache配置。最后运行复杂的脚本,模拟多种角色的用户在不同时间下的处理,以测试网站压力负载。




    展开全文
  • 史上最强Tomcat8性能优化

    万次阅读 多人点赞 2019-10-25 15:33:32
    文章目录授人以鱼不如授人以渔目的服务器资源Tomcat配置优化Linux环境安装运行Tomcat8AJP连接执行器(线程池)3种运行模式部署测试用的web项目...测试报告调整Tomcat参数进行优化禁用AJP连接设置线程池最大线程数为150...

    授人以鱼不如授人以渔

    本博客的目的不在于给出最佳配置,而是带领开发者,能够从实际情况出发,通过不断的调节tomcat和jvm参数,去发现吞吐量,平均响应时间和错误率等信息的变化,同时根据服务器的cpu和内存等信息,结合接口的业务逻辑,最好是测试使用率最高,并发最大,或者是最重要的接口(比如下单支付接口),设置最优的tomcat和jvm配置参数。

    目的

    通过Tomcat性能优化可以提高网站的并发能力。

    Tomcat服务器在JavaEE项目中使用率非常高,所以在生产环境对Tomcat的优化也变得非常重要了。

    对于Tomcat的优化,主要是从2个方面入手,一是Tomcat自身的配置,另一个是Tomcat所运行的jvm虚拟机的调优。

    服务器资源

    服务器所能提供CPU、内存、硬盘的性能对处理能力有决定性影响。硬件我们不说了,这个方面是钱越多越好是吧。

    Tomcat配置优化

    Linux环境安装运行Tomcat8

    具体的安装步骤可以参考Linux(CentOS7)安装Tomcat与设置Tomcat为开机启动项

    如果需要登录系统,必须配置tomcat用户,在安装完Tomcat后,进行如下操作

    /conf/tomcat-users.xml文件中的<tomcat-users>标签里面添加如下内容

    <!-- 修改配置文件,配置tomcat的管理用户 -->
    <role rolename="manager"/>
    <role rolename="manager-gui"/>
    <role rolename="admin"/>
    <role rolename="admin-gui"/>
    <user username="tomcat" password="tomcat" roles="admin-gui,admin,manager-gui,manager"/>
    

    如果是tomcat7,配置了tomcat用户就可以登录系统了,但是tomcat8中不行,还需要修改另一个配置文件,否则访问不了,提示403,打开webapps/manager/META-INF/context.xml文件

    <!-- 将Valve标签的内容注释掉,保存退出即可 -->
    <?xml version="1.0" encoding="UTF-8"?>
    
    <Context antiResourceLocking="false" privileged="true" >
      <!--<Valve className="org.apache.catalina.valves.RemoteAddrValve"
             allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />-->
      <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
    </Context>
    

    打开浏览器进行访问10.172.0.202:8080

    在这里插入图片描述

    点击“Server Status”,输入用户名、密码进行登录,tomcat/tomcat

    在这里插入图片描述

    登录之后可以看到服务器状态等信息,主要包括服务器信息,JVM,ajp和http信息

    在这里插入图片描述

    AJP连接

    在服务状态页面中可以看到,默认状态下会启用AJP服务,并且占用8009端口。

    在这里插入图片描述

    什么是AJP

    AJP(Apache JServer Protocol)
    AJPv13协议是面向包的。WEB服务器和Servlet容器通过TCP连接来交互;为了节省SOCKET创建的昂贵代价,WEB服务器会尝试维护一个永久TCP连接到servlet容器,并且在多个请求和响应周期过程会重用连接。

    在这里插入图片描述

    我们一般是使用Nginx+Tomcat的架构,所以用不着AJP协议,把AJP连接器禁用。

    修改conf下的server.xml文件,将AJP服务禁用掉即可。

    <!-- 禁用AJP连接 -->
    <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
    

    在这里插入图片描述

    重启tomcat,查看效果。可以看到AJP服务已经不存在了。

    在这里插入图片描述

    执行器(线程池)

    在tomcat中每一个用户请求都是一个线程,所以可以使用线程池提高性能。

    修改server.xml文件:

    <!--将注释打开-->
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="500" minSpareThreads="50" prestartminSpareThreads="true" maxQueueSize="100"/>
    
    <!--
    参数说明:
    maxThreads:最大并发数,默认设置 200,一般建议在 500 ~ 1000,根据硬件设施和业务来判断
    minSpareThreads:Tomcat 初始化时创建的线程数,默认设置 25
    prestartminSpareThreads: 在 Tomcat 初始化的时候就初始化 minSpareThreads 的参数值,如果不等于 true,minSpareThreads 的值就没啥效果了
    maxQueueSize,最大的等待队列数,超过则拒绝请求
    -->
    
    <!--在Connector中设置executor属性指向上面的执行器-->
    <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    

    保存退出,重启tomcat,查看效果。

    在这里插入图片描述

    在页面中显示最大线程数为-1,这个是正常的,仅仅是显示的问题,实际使用的是指定的值。如果配置了一个Executor,则该属性的任何值将被正确记录,但是它将被显示为-1

    3种运行模式

    tomcat的运行模式有3种:

    bio
    性能非常低下,没有经过任何优化处理和支持

    nio
    nio(new I/O),是Java SE 1.4及后续版本提供的一种新的I/O操作方式(即java.nio包及其子包)。Java nio是一个基于缓冲区、并能提供非阻塞I/O操作的Java API,因此nio也被看成是non-blocking I/O的缩写。它拥有比传统I/O操作(bio)更好的并发运行性能。Tomcat8默认使用nio运行模式

    apr
    安装起来最困难,但是从操作系统级别来解决异步的IO问题,大幅度的提高性能

    对于每种协议,Tomcat都提供了对应的I/O方式的实现,而且Tomcat官方还提供了在每种协议下每种I/O实现方案的差异, HTTP协议下的处理方式如下表,详情可查看Tomcat官网说明

    BIONIONIO2APR
    类名Http11ProtocolHttp11NioProtocolHttp11Nio2ProtocolHttp11AprProtocol
    引用版本≥3.0≥6.0≥8.0≥5.5
    轮询支持
    轮询队列大小N/AmaxConnectionsmaxConnectionsmaxConnections
    读请求头阻塞非阻塞非阻塞阻塞
    读请求体阻塞阻塞阻塞阻塞
    写响应阻塞阻塞阻塞阻塞
    等待新请求阻塞非阻塞非阻塞非阻塞
    SSL支持Java SSLJava SSLJava SSLOpen SSL
    SSL握手阻塞非阻塞非阻塞阻塞
    最大链接数maxConnectionsmaxConnectionsmaxConnectionsmaxConnections

    推荐使用nio,在tomcat8中有最新的nio2,速度更快,建议使用nio2

    设置nio2:

    <Connector executor="tomcatThreadPool"  port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    

    在这里插入图片描述

    可以看到已经设置为nio2了。

    部署测试用的web项目

    为了方便测试性能,我们将部署一个java web项目,这个项目本身和本博客没有什么关系,仅仅用于测试。

    注意:这里在测试时,我们使用一个新的tomcat,进行测试,后面再对其进行优化调整,再测试。

    查看服务器信息

    说明一下我的测试服务器配置,不同的服务器配置对Tomcat的性能会有所影响。

    配置参数参数值
    Linux版本CentOS Linux release 7.2.1511 (Core)
    查看逻辑cpu个数4
    查看物理cpu个数4
    总内存8G

    CentOS7服务器环境信息查看命令

    查看Linux版本

    查看Linux版本:cat /etc/centos-release

    查看CPU个数

    查看逻辑cpu个数:cat /proc/cpuinfo | grep “processor” | wc -l

    查看物理cpu个数:cat /proc/cpuinfo | grep “physical id” | sort | uniq | wc -l

    查看每个物理cpu的核数cores:cat /proc/cpuinfo | grep “cpu cores”

    如果所有物理cpu的cores个数加起来小于逻辑cpu的个数,则该cpu使用了超线程技术。查看每个物理cpu中逻辑cpu的个数:cat /proc/cpuinfo | grep “siblings”

    查看内存使用情况

    查看内存占用情况:free -m

    参数说明

    Mem:内存的使用情况总览表。

    total:机器总的物理内存 单位为:M

    used:用掉的内存。

    free:空闲的物理内存。

    [root@localhost ~]# cat /etc/centos-release
    CentOS Linux release 7.2.1511 (Core)
    
    [root@localhost ~]# cat /proc/cpuinfo | grep "processor" | wc -l
    4
    [root@localhost ~]# cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l
    4
    
    [root@localhost ~]# cat /proc/cpuinfo | grep "cpu cores"
    cpu cores       : 1
    cpu cores       : 1
    cpu cores       : 1
    cpu cores       : 1
    
    [root@localhost ~]# free -m
                  total        used        free      shared  buff/cache   available
    Mem:           7825         850        6241           9         733        6714
    Swap:          8063           0        8063
    

    部署web应用

    上传war包到linux服务器,然后进行部署

    我的web应用的名字叫tomcat-optimization,主要是提供了一个查询用户列表的接口,该接口会去阿里云数据库查询用户列表,没有任务业务逻辑的处理

    # 删除tomcat的/webapps/ROOT目录的所有文件
    cd /webapps/ROOT
    rm -rf *
    
    # 上传war包到tomcat的/webapps/ROOT,然后解压
    jar -xvf tomcat-optimization.war
    rm -rf tomcat-optimization.war
    
    # 进入tomcat的/bin目录重启tomcat
    cd /bin
    ./shutdown.sh
    ./startup.sh
    

    访问接口地址: http://10.172.0.202:8080/user/listUser

    [{
    	"id": 1,
    	"account": "lilei",
    	"password": "123456",
    	"userName": "李雷",
    	"gender": 1,
    	"age": 15,
    	"birthday": "2001-01-01 01:01:38",
    	"createTime": "2016-03-01 19:09:55"
    }, {
    	"id": 2,
    	"account": "hanmeimei",
    	"password": "123456",
    	"userName": "韩梅梅",
    	"gender": 0,
    	"age": 14,
    	"birthday": "2002-01-01 01:01:38",
    	"createTime": "2016-03-01 19:09:55"
    }, {
    	"id": 3,
    	"account": "lucy",
    	"password": "123456",
    	"userName": "露西",
    	"gender": 0,
    	"age": 13,
    	"birthday": "2003-01-01 01:01:38",
    	"createTime": "2016-03-01 19:09:55"
    }]
    

    使用Apache JMeter进行性能测试

    Apache JMeter是Apache组织开发的基于Java的压力测试工具。 我们借助于此工具进行测试,将测试出tomcat的吞吐量等信息。

    下载安装

    下载地址:http://jmeter.apache.org/download_jmeter.cgi

    在这里插入图片描述

    注意:这里需要先安装好jdk8及其以上版本的环境,可以参考JDK安装与环境变量配置

    直接将下载好的zip压缩包进行解压即可。

    在这里插入图片描述

    进入bin目录,找到jmeter.bat文件,双机打开即可启动。

    在这里插入图片描述

    JMeter启动页面

    在这里插入图片描述

    JMeter主页面

    在这里插入图片描述

    修改语言

    默认的主题是黑色风格的主题并且语言是英语,这样不太方便使用,所以需要修改下语言。

    设置语言为简体中文。

    在这里插入图片描述

    修改语言完成的界面

    在这里插入图片描述

    创建接口的测试用例

    测试接口之前需要调整Windows环境配置,不然会报如下错误

    JMeter java.net.BindException: Address already in use: connect
    

    出现原因
    TCP/IP连接数不够或TIME_WAIT中存在很多链接,导致吞吐量低。

    解决方案
    从问题的原因分析,有两种解决方案,一是增加预留给TCP/IP服务的临时端口的数量,二是加快被占用端口的释放速度。

    解决办法
    1、打开注册表:regedit
    2、HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ Services\TCPIP\Parameters
    3、新建 DWORD值,name:TCPTimedWaitDelay,value:30(十进制) –> 设置为30秒,默认是240秒
    4、新建 DWORD值,name:MaxUserPort,value:65534(十进制) –> 设置最大连接数65534
    5、重启系统

    第一步:设置测试计划的名称

    在这里插入图片描述

    第二步:添加线程组,使用线程模拟用户的并发

    在这里插入图片描述

    在这里插入图片描述

    1000个线程,每个线程循环10次,也就是tomcat会接收到10000个请求。

    第三步:添加http请求

    在这里插入图片描述

    设置http请求

    在这里插入图片描述

    第四步:添加请求监控

    在这里插入图片描述

    启动与进行接口测试

    在这里插入图片描述

    查看测试报告

    在聚合报告中,重点看吞吐量。

    在这里插入图片描述

    调整Tomcat参数进行优化

    通过上面测试可以看出,tomcat在不做任何调整时,吞吐量为697次/秒。这个吞吐量跟接口的业务逻辑关系很大,如果业务逻辑复杂,需要比较长时间计算的,可能吞吐量只有几十次/秒,我这里测试的时候没有添加任务业务逻辑,才会出现吞吐量为697次/秒的情况。这里的吞吐量最好是经过多次测试取平均值,因为单次测试具有一定的随机性

    禁用AJP连接

    修改conf下的server.xml文件,将AJP服务禁用掉即可。

    <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
    

    在这里插入图片描述

    在这里插入图片描述

    这里经过9次测试,测试结果如下704 730 736 728 730 727 714 708 735 平均是723

    可以看到,禁用AJP服务后,吞吐量会有所提升。

    当然了,测试不一定准确,需要多测试几次才能看出是否有提升。

    设置线程池

    通过设置线程池,调整线程池相关的参数进行测试tomcat的性能。有关线程池更多更详细的配置参考Tomcat官网提供的配置详解

    最大线程数为150,初始为4

    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="150" minSpareThreads="4" prestartminSpareThreads="true"/>
    
    <!--在Connector中设置executor属性指向上面的执行器-->
    <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    

    在这里插入图片描述

    经过9次测试,测试结果如下705 725 702 729 733 738 735 728 平均是724

    最大线程数为500,初始为50

    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="500" minSpareThreads="50" prestartminSpareThreads="true"/>
    
    <!--在Connector中设置executor属性指向上面的执行器-->
    <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    

    测试结果:733 724 718 728 734 721 720 723 平均725

    吞吐量为725次/秒,性能有所提升。

    最大线程数为1000,初始为200

    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="1000" minSpareThreads="200" prestartminSpareThreads="true"/>
    
    <!--在Connector中设置executor属性指向上面的执行器-->
    <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    

    吞吐量为732,性能有所提升。

    测试结果 737 729 730 738 735 726 725 740 平均732

    最大线程数为5000,初始为1000

    是否是线程数最多,速度越快呢? 我们来测试下。

    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="5000" minSpareThreads="1000" prestartminSpareThreads="true"/>
    
    <!--在Connector中设置executor属性指向上面的执行器-->
    <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    

    测试结果 727 733 728 725 738 729 737 735 739 平均732

    可以看到,虽然最大线程已经设置到5000,但是实际测试效果并不理想,并且平均的响应时间也边长了,所以单纯靠提升线程数量是不能一直得到性能提升的。

    设置最大等待队列数

    默认情况下,请求发送到tomcat,如果tomcat正忙,那么该请求会一直等待。这样虽然可以保证每个请求都能请求到,但是请求时间就会边长。

    有些时候,我们也不一定要求请求一定等待,可以设置最大等待队列大小,如果超过就不等待了。这样虽然有些请求是失败的,但是请求时间会虽短。典型的应用:12306。

    <!--最大等待数为100-->
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="500" minSpareThreads="100" prestartminSpareThreads="true" maxQueueSize="100"/>
    
    <!--在Connector中设置executor属性指向上面的执行器-->
    <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    

    在这里插入图片描述

    测试结果:

    • 平均响应时间:0.438秒,响应时间明显缩短
    • 错误率:43.07%,错误率超过40%,也可以理解,最大线程为500,测试的并发为1000
    • 吞吐量:1359次/秒,吞吐量明显提升

    结论:响应时间、吞吐量这2个指标需要找到平衡才能达到更好的性能。

    设置nio2的运行模式

    将最大线程设置为500进行测试:

    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="500" minSpareThreads="100" prestartminSpareThreads="true"/>
    
    <!-- 设置nio2 -->
    <Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    

    从测试结果可以看到,平均响应时间有缩短,吞吐量有提升,可以得出结论:nio2的性能要高于nio。

    参数说明与最佳实践

    具体参数参考官网说明

    执行器参数说明(加粗是重点)

    AttributeDescription
    threadPriority (优先级)(int) 执行程序中线程的线程优先级,默认值为 5Thread.NORM_PRIORITY常量的值)
    daemon(守护进程)(布尔) 线程是否应该是守护程序线程,默认值为 true
    namePrefix(名称前缀)(String) 执行程序创建的每个线程的名称前缀。单个线程的线程名称将为namePrefix+threadNumber
    maxThreads(最大线程数)(int) 此池中活动线程的最大数量,默认为 200
    minSpareThreads(最小活跃线程数)(int) 始终保持活动状态的最小线程数(空闲和活动),默认值为 25
    maxIdleTime(空闲线程等待时间)(int) 空闲线程关闭之前的毫秒数,除非活动线程的数目小于或等于minSpareThreads。默认值为60000(1分钟)
    maxQueueSize(最大的等待队里数,超过则请求拒绝)(int) 在我们拒绝执行之前可以排队等待执行的可运行任务的最大数量。默认值为Integer.MAX_VALUE
    prestartminSpareThreads(是否在启动时就生成minSpareThreads个线程)(boolean) 在启动执行程序时是否应启动minSpareThreads,默认值为 false
    threadRenewalDelay(重建线程的时间间隔)(long) 如果配置了ThreadLocalLeakPreventionListener,它将通知该执行程序已停止的上下文。上下文停止后,池中的线程将更新。为避免同时更新所有线程,此选项设置了任意两个线程之间的延迟。该值以毫秒为单位,默认值为1000ms。如果值为负,则不更新线程。

    执行器最佳实践

    此最佳配置仅供参考

    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="800" minSpareThreads="100" maxQueueSize="100"                                 prestartminSpareThreads="true"/>
    

    连接器参数说明

    可以看到除了这几个基本配置外并无特殊功能,所以我们需要对 Connector 进行扩展。

    其中Connector 支持参数属性可以参考Tomcat官方网站,本文就只介绍些常用的。

    通用属性(加粗是重点)
    AttributeDescription
    allowTrace如果需要服务器能够处理用户的HAED/TRACE请求,这个值应该设置为true,默认值是false
    asyncTimeout默认超不时候以毫秒为单位的异步恳求。若是没有指定,该属性被设置为10000(10秒)
    enableLookups设置为true是否要调用以 request.getRemoteHost()执行DNS查找以返回远程客户端的实际主机名。设置为false跳过DNS查找并改为以字符串形式返回IP地址(从而提高性能)。默认情况下,DNS查找被禁用。
    maxHeaderCount容器允许的请求头字段的最大数目。请求中包含比指定的限制更多的头字段将被拒绝。值小于0表示没有限制。如果没有指定,默认设置为100。
    maxParameterCount将被容器自动解析的最大数量的参数和值对(GET加上POST)。参数值对超出此限制将被忽略。值小于0表示没有限制。如果没有指定,默认为10000。请注意, FailedRequestFilter 过滤器可以用来拒绝达到了极限值的请求。
    maxPostSize容器FORM URL参数解析将处理的POST的最大大小(以字节为单位)。可以通过将此属性设置为小于零的值来禁用该限制。如果未指定,则此属性设置为2097152(2兆字节)。请注意, FailedRequestFilter 可以使用拒绝超过此限制的请求。
    maxSavePostSize将被容器在FORM或CLIENT-CERT认证中保存/缓冲的POST的最大尺寸(以字节为单位)。对于这两种类型的身份验证,在用户身份验证之 前,POST将被保存/缓冲。对于POST CLIENT-CERT认证,处理该请求的SSL握手和缓冲清空期间,POST将被缓存。对于Form认证,POST将被保存,同时用户将被重定向到登陆 表单。POST将被一直保留直到用户成功认证或者认证请求关联的会话超时。将此属性设置为-1可以禁用此限制。将此属性设置为0,POST数据在身份验证 过程中将不被保存。如果没有指定,该属性设置为4096(4千字节)。
    parseBodyMethods以逗号分隔的HTTP方法列表,通过方法列表,等同于POST方法,request 正文将被解析成请求参数。这在RESTful应用程序要支持以POST式的语义解析PUT请求中是非常有用的。需要注意的是设置其他值(不是POST)会导致Tomcat的行为违反servlet规范的目的。在这里为了符合HTTP规范明确禁止HTTP方法TRACE。默认值是POST
    port连接器 将在其上创建服务器套接字并等待传入连接的TCP端口号。您的操作系统将仅允许一个服务器应用程序侦听特定IP地址上的特定端口号。如果使用特殊值0(零),则Tomcat将随机选择一个空闲端口用于此连接器。这通常仅在嵌入式和测试应用程序中有用。
    protocol设置协议以处理传入流量。默认值为 HTTP/1.1使用自动切换机制选择基于Java NIO的连接器或基于APR / native的连接器。如果PATH(Windows)或LD_LIBRARY_PATH(在大多数Unix系统上)环境变量包含Tomcat本机库,并且AprLifecycleListener用于初始化APR的库的useAprConnector属性设置为 true,则将使用APR /本机连接器。如果找不到本机库或未配置属性,则将使用基于Java NIO的连接器。请注意,APR /本机连接器的HTTPS设置与Java连接器的设置不同。
    要使用显式协议而不是依赖于上述自动切换机制,可以使用以下值:
    org.apache.coyote.http11.Http11NioProtocol-非阻塞Java NIO连接器
    org.apache.coyote.http11.Http11Nio2Protocol-非阻塞Java NIO2连接器-APR
    org.apache.coyote.http11.Http11AprProtocol/本地连接器。
    也可以使用自定义实现。
    看看我们的连接器比较表。对于Java和Java连接器,http和https的配置相同。
    有关APR连接器和特定于APR的SSL设置的更多信息,请访问APR文档
    proxyName如果这个连接正在使用的代理服务器配置,配置该属性指定的服务器的名称,可以调用request.getServerName()返回。有关更多信息,请参见代理支持。
    proxyPort如果这个连接正在使用的代理服务器配置,配置该属性指定服务器端口,可以调用request.getServerPort()返回。有关更多信息,请参见代理支持。
    redirectPort如果该连接器支持非SSL请求,并且接收到的请求为满足安全约束需要SSL传输, Catalina 将自动将请求重定向到指定的端口号。
    scheme将该属性设置为你想调用request.getScheme()返回的协议的名称。例如,对于SSL连接器,你会将此属性设置为“HTTPS ”。默认值是“ HTTP ”。
    secure如果你想调用request.isSecure()收到此连接器的请求返回true,请该该属性设置为true。您希望SSL连接器或非SSL连接器接收数据通过一个SSL加速器,像加密卡,SSL设备,甚至一个web服务器。默认值是假的。
    URIEncoding解决我们的乱码问题,这将指定使用的字符编码,来解码URI字符。如果没有指定,ISO-8859-1将被使用。
    useBodyEncodingForURI这指定是否应该用于URI查询参数,而不是使用URIEncoding contentType中指定的编码。此设置兼容性Tomcat 4.1.x版(该版在contentType中指定编码,或者使用request.setCharacterEncoding的方法显式设置(参数为 URL传来的值)。默认值false。
    useIPVHosts将该属性设置为true会导致Tomcat使用收到请求的IP地址,来确定将请求发送到哪个主机。默认值是假的。
    xpoweredBy将此属性设置为true会导致Tomcat支持使用Servlet规范的通知,(在规范中推荐使用头字段)。默认值是假的。
    标准实现(加粗是重点)

    除了上面列出的常见的连接器属性,标准的HTTP连接器(BIO,NIO和APR/native)都支持以下属性。

    AttributeDescription
    acceptCount当所有可能的请求处理线程都在使用时,传入连接请求的最大队列长度。当队列满时收到的任何请求将被拒绝。默认值是100。
    acceptorThreadCount用于接受连接的线程的数量。在一个多CPU的机器上,增加该值,虽然你可能不会真正需要超过2个。此外,有很多非保持活动连接,您可能需要增加这个值。默认值是 1。
    acceptorThreadPriority接收器线程的优先级。该线程用来接受新的连接。默认值是5(java.lang.Thread.NORM_PRIORITY常量)。更多这个优先级是什么意思的详细信息,请查看java.lang.Thread的类的JavaDoc 。
    address对于拥有多个IP地址的服务器,该属性指定哪个地址将被用于在指定端口上监听。默认情况下,该端口将被用于与服务器相关联的所有IP地址。
    bindOnInit控制连接器绑定时套接字的使用。缺省情况,当连接器被启动时套接字被绑定和当连接器被销毁时套接字解除绑定。如果设置为false,连接器启动时套接字被绑定,连接器停止时套接字解除绑定。
    compressableMimeType该值是一个被用于HTTP压缩的逗号分隔的MIME类型列表。默认值是text / html类型,为text / xml,text / plain。
    compression通常会在ngnix里面配置压缩 ,开启压缩GZIP 为了节省服务器带宽,连接器可以使用HTTP/1.1 GZIP压缩。可接受的参数的值是“off ”(禁用压缩),“on ”(允许压缩,这会导致文本数据被压缩),“force ”(强制在所有的情况下压缩),或者一个整数值(这是相当于为“on”,但指定了输出之前被压缩的数据最小量)。如果不知道内容长度但被设置为“on”或更积极的压缩,输出的数据也将被压缩。如果没有指定,该属性被设置为“关”。 注意:这是使用压缩(节省您的带宽)和使用sendfile功能(节省你的CPU周期)之间的权衡。如果连接器支持sendfile功能,例如NIO连接,则使用sendfile将优先于压缩。症状是48 KB的静态文件将未压缩就发送。你可以如下文所述通过设置连接器的useSendfile属性来关闭sendfile,或在默认的conf/web.xml或者你的web应用的web.xml中配置DefaultServlet来改变sendfile的使用量阈值。
    compressionMinSize如果压缩被设置为“on”,那么该属性可以用于指定在输出之前被压缩的数据的最小量。如果未指定,此属性默认为“2048”。
    connectionLinger连接器的套接字被关闭时的逗留秒数。如果没有指定,将使用默认的JVM。
    connectionTimeout在将提交的请求URI行呈现之后,连接器将等待接受连接的毫秒数。使用值-1表示没有超时(即无限)。默认值是60000(60秒),但请注意,Tomcat的标准server.xml中,设置为20000(即20秒)。
    connectionUploadTimeout上传数据过程中,指定的以毫秒为单位超时时间。只有在设置disableUploadTimeout为false有效。
    disableUploadTimeout此标志允许servlet容器在数据上传时使用不同的连接超时,通常较长。如果没有指定,该属性被设置为true,禁用上传超时。
    executor指向Executor元素的引用。如果这个属性被设置,并且被命名的executor存在,连接器将使用这个executor,而其他所有线程相关属性将被忽略。请注意共享的executor如果没有指定到一个连接器,则该连接器将使用一个私有的,内部的executor来提供线程池。
    executorTerminationTimeoutMillisThe time that the private internal executor will wait for request processing threads to terminate before continuing with the process of stopping the connector. If not set, the default is 0 (zero) for the BIO connector and 5000 (5 seconds) for the NIO and APR/native connectors.
    keepAliveTimeout此连接器在关闭连接之前将等待另一个HTTP请求的毫秒数。默认值是使用已设置的connectionTimeout属性的值。使用值-1表示没有超时(即无限)。
    maxConnections在任何给定的时间服务器接受并处理的最大连接数。当这个数字已经达到了,服务器将不会接受任何连接,直到连接的数量降到低于此值。基于acceptCount的设置,操作系统可能仍然接受连接。默认值根据不同的连接器类型而不同。对于BIO,默认的是maxThreads的值,除非使用了Executor,在这种情况下默认值是executor的maxThreads值 。对于NIO的默认值是10000。APR /native的默认值是8192。 需要注意的是Windows系统的APR/native,所配置的值将减少到小于或等于maxConnections的1024的倍数的最大值。这样做是出于性能方面的考虑。如果设置的值-1,maxConnections功能被禁用,而且连接数将不做计算。
    maxExtensionSize限制HTTP区块请求中区块扩展的总长度。如果值为-1,则不施加任何限制。如果未指定,8192将使用默认值。
    maxHttpHeaderSize请求和响应的HTTP头的(以字节为单位的)最大尺寸。如果没有指定,该属性被设置为8192(8 KB)。
    maxKeepAliveRequestsHTTP请求最大长连接个数。将此属性设置为1,将禁用HTTP/1.0、以及HTTP/1.1的长连接。设置为-1,不禁用。如果没有指定,该属性被设置为100。
    maxSwallowSizeTomcat会为中止的上载而吞下的请求正文字节的最大数量(不包括传输编码开销)。上载中止是指Tomcat知道将忽略请求主体,但客户端仍将其发送。如果Tomcat不吞咽该主体,则客户端不太可能看到响应。如果未指定,将使用默认值2097152(2兆字节)。小于零的值表示不应强制执行任何限制。
    maxThreads最多同时处理的连接数,Tomcat使用线程来处理接收的每个请求。这个值表示Tomcat可创建的最大的线程数。如果没有指定,该属性被设置为200。如果使用了execute将忽略此连接器的该属性,连接器将使用execute,而不是一个内部线程池来处理请求。
    maxTrailerSize限制一个分块的HTTP请求中的最后一个块的尾随标头的总长度。如果该值是-1,没有限制的被强加。如果没有指定,默认值是8192。
    minSpareThreads始终保持运行最小线程数。如果没有指定,则默认为10。
    noCompressionUserAgents该值是一个正则表达式(使用java.util.regex),匹配不应该使用压缩的HTTP客户端的用户代理标头。因为这些客户端,虽然他们宣称支持压缩功能,但实现不完整。默认值是一个空字符串(正则表达式匹配禁用)。
    processorCache协议处理器缓存Processor对象以提高性能。此设置规定了这些对象有多少能得到缓存。-1意味着无限制,默认为200。如果不使用Servlet 3.0的异步处理,一个好的默认是使用maxThreads设置。如果使用Servlet 3.0的异步处理,一个好的默认是使用maxThreads和最大预期的并发请求(同步和异步)的最大值中的较大值。
    restrictedUserAgents该值是一个正则表达式(使用java.util.regex),匹配用户代理头的HTTP浏览器将不能使用HTTP/1.1或HTTP/1.0长连接,即使该浏览器宣称支持这些功能的。默认值是一个空字符串(正则表达式匹配禁用)。
    server覆盖服务器的HTTP响应头。如果设置了这个属性的值将覆盖Web应用程序设置的Tomcat的默认头和任何服务器头。如果没有设置,应用程序指定的任何值将被使用。如果应用程序没有指定一个值,那么Apache-Coyote/1.1将被使用。除非你是偏执狂,你将不再需要此功能。
    socketBuffer为套接字输出缓冲而提供的缓冲区的大小(以字节为单位)。-1可以被指定来禁止使用的缓冲区。默认情况下,一个9000个字节的缓冲区将被使用。
    SSLEnabled在连接器上使用此属性来启用SSL加密传输。如果要打开SSL握手/加密/解密,请设置true。默认值是false。当设置这个值为true时,为了传递正确的request.getScheme()和 request.isSecure()到servlets,你需要设置scheme和secure属性。更多信息请查看SSL支持。
    tcpNoDelay如果设置为true,TCP_NO_DELAY选项将被设置在服务器上的套接字上,在大多数情况下,这样可以提高性能。默认设置为true。
    threadPriority在JVM中请求处理线程的优先级。默认值是5(java.lang.Thread.NORM_PRIORITY常量值)。关于优先级的更多详细信息,请查看java.lang.Thread的类的JavaDoc
    upgradeAsyncWriteBufferSizeThe default size of the buffer to allocate to for asynchronous writes that can not be completed in a single operation. Data that can’t be written immediately will be stored in this buffer until it can be written. If more data needs to be stored than space is available in the buffer than the size of the buffer will be increased for the duration of the write. If not specified the default value of 8192 will be used.

    连接器最佳实践

    此最佳配置仅供参考

    <Connector executor="tomcatThreadPool" port="8080" 						                            protocol="org.apache.coyote.http11.Http11Nio2Protocol" 
               connectionTimeout="20000" redirectPort="8443" 
               enableLookups="false" maxPostSize="10485760" URIEncoding="UTF-8" 	                    acceptCount="100" acceptorThreadCount="2" disableUploadTimeout="true"                    maxConnections="10000" SSLEnabled="false"/>
    

    调整JVM参数进行优化

    接下来,通过设置jvm参数进行优化,为了测试一致性,依然将最大线程数设置为500,启用nio2运行模式

    设置并行垃圾回收器

    在/bin/catalina.sh文件第一行添加如下参数,gc日志输出到/logs/gc.log

    #年轻代、老年代均使用并行收集器,初始堆内存64M,最大堆内存512M
    JAVA_OPTS="-XX:+UseParallelGC -XX:+UseParallelOldGC -Xms64m -Xmx512m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:../logs/gc.log"
    

    在这里插入图片描述

    测试结果与默认的JVM参数结果接近。

    查看gc日志文件

    将gc.log文件上传到gceasy.io查看gc中是否存在问题。上传文件后需要等待一段时间,需要耐心等待。

    在这里插入图片描述

    问题一:系统所消耗的时间大于用户时间

    在这里插入图片描述

    如果在报告中显示System Time greater than User Time,系统所消耗的时间大于用户时间,这反应出的服务器的性能存在瓶颈,调度CPU等资源所消耗的时间要长一些。

    问题二:线程暂停时间有点长

    在这里插入图片描述

    可以关键指标中可以看出,吞吐量表现不错,但是gc时,线程的暂停时间稍有点长。

    问题三:GC总次数过多

    在这里插入图片描述

    通过GC的统计可以看出:

    • 年轻代的gc有100次,次数有点多,说明年轻代设置的大小不合适,需要调整
    • FullGC有7次,说明堆内存的大小不合适,需要调整

    问题四:年轻代内存不足导致GC

    在这里插入图片描述

    从GC原因的可以看出,年轻代大小设置不合理,导致了多次GC。

    调整年轻代大小

    调整jvm配置参数

    JAVA_OPTS="-XX:+UseParallelGC -XX:+UseParallelOldGC -Xms128m -Xmx1024m -XX:NewSize=64m -XX:MaxNewSize=256m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:../logs/gc.log"
    

    将初始堆大小设置为128m,最大为1024m,初始年轻代大小64m,年轻代最大256m

    在这里插入图片描述

    从测试结果来看,吞吐量以及响应时间均有提升。

    查看gc日志

    在这里插入图片描述

    可以看到GC次数要明显减少,说明调整是有效的。

    在这里插入图片描述

    GC次数有所减少

    在这里插入图片描述

    设置G1垃圾回收器

    #设置了最大停顿时间100毫秒,初始堆内存128m,最大堆内存1024m
    JAVA_OPTS="-XX:+UseG1GC -XX:MaxGCPauseMillis=100 -Xms128m -Xmx1024m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:../logs/gc.log"
    

    测试结果

    在这里插入图片描述

    可以看到,吞吐量有所提升,评价响应时间也有所缩短。

    在这里插入图片描述

    G1集合阶段统计

    在这里插入图片描述

    JVM配置最佳实践

    此最佳配置仅供参考

    JAVA_OPTS="-Dfile.encoding=UTF-8-server -Xms1024m -Xmx2048m -XX:NewSize=512m -XX:MaxNewSize=1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:MaxTenuringThreshold=10-XX:NewRatio=2 -XX:+DisableExplicitGC"
    

    参数说明

    file.encoding 默认文件编码

    -Xmx1024m 设置JVM最大可用内存为1024MB

    -Xms1024m 设置JVM最小内存为1024m。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。

    -XX:NewSize 设置年轻代大小

    -XX:MaxNewSize 设置最大的年轻代大小

    -XX:PermSize 设置永久代大小

    -XX:MaxPermSize 设置最大永久代大小

    -XX:NewRatio=4 设置年轻代(包括Eden和两个Survivor区)与终身代的比值(除去永久代)。设置为4,则年轻代与终身代所占比值为1:4,年轻代占整个堆栈的1/5

    -XX:MaxTenuringThreshold=0 设置垃圾最大年龄,默认为:15。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。

    -XX:+DisableExplicitGC 这个将会忽略手动调用GC的代码使得System.gc()的调用就会变成一个空调用,完全不会触发任何GC。

    总结

    通过上述的测试,可以总结出,对tomcat性能优化就是需要不断的进行调整参数,然后测试结果,可能会调优也可能会调差,这时就需要借助于gc的可视化工具来看gc的情况。再帮我我们做出决策应该调整哪些参数。

    再次重申本博客的目的不在于给出最佳配置,而是带领开发者,能够从实际情况出发,通过不断的调节tomcat和jvm参数,去发现吞吐量,平均响应时间和错误率等信息的变化,同时根据服务器的cpu和内存等信息,结合接口的业务逻辑,最好是测试使用率最高,并发最大,或者是最重要的接口(比如下单支付接口),设置最优的tomcat和jvm配置参数

    展开全文
  • 去年做一个数字电视监测的项目,每天大约120万的流量,当然这个总流量意义不是很大,考量应用服务的承受能力主要看峰值压力的承受能力和持续时间。 大概测试报告如下,完整测试还包括对主体业务的影响等不方便全部列...
  • Tomcat和应用程序进行了压力测试后,如果您对应用程序的性能结果不太满意,就可以采取一些性能调整措施了,当然了前提是应用程序没有问题, 我们这里 只讲Tomcat的调整。由于Tomcat的运行依赖于JVM,所以在...
  • 安全优化 管理端口保护 在server.xml文件下把管理端口和口令修改一下,防止图谋不轨的人telnet上来关掉我的tomcat: ajp连接端口保护 Apache JServ协议1.3版(简称ajp13)是一个二进制的TCP传输协议,相比当前...
  • Tomcat压力优化

    2015-04-08 14:01:53
    Tomcat和应用程序进行了压力测试后,如果您对应用程序的性能结果不太满意,就可以采取一些性能调整措施了,当然了前提是应用程序没有问题,我们这里只讲Tomcat的调整。由于Tomcat的运行依赖于JVM,所以在这里我们...
  • tomcat优化jmeter压力测试springboot-tomcat调优 使用背景:多文件上传批量处理,提高用户的体验,在上传大量文件采用异步处理,那么需要提高上传接口的并发量,我压力测试该接口,出现连接被拒接的情况 jmeter压力...
  • 本文主要使用jmeter工具对tomcat8进行压力测试,并使用java visualVM进行压测性能监控,通过监控数据调整tomcat参数 步入正题: 首先操作系统已优化完成,java版本为1.8以上,tomcat版本8.0.48,根据自己实际情况而定 ...
  • 最强Tomcat8性能优化

    2020-10-10 09:08:33
    去发现吞吐量,平均响应时间和错误率等信息的变化,同时根据服务器的cpu和内存等信息,结合接口的业务逻辑,最好是测试使用率最高,并发最大,或者是最重要的接口(比如下单支付接口),设置最优的tomcat和jvm配置参数...
  • tomcat 压力测试调优+参数配置

    千次阅读 2014-07-18 12:14:57
    1.压力测试的时候,当并发数达到100的时候,tomcat的线程数和连接池都出现了问题,需修改配置如下   port="8033" maxThreads="1000" minSpareThreads="55" maxSpareThreads="1000" enableLookups="false" ...
  • 一: Tomcat内存优化 启动时告诉JVM我要一块大内存(调优内存是最直接的方式) Windows 下的catalina.bat Linux 下的catalina.sh 如: JAVA_OPTS='-Xms256m -Xmx512m' -Xms JVM初始化堆的大小 -Xmx JVM堆的最大值 ...
  • 本文主要包括Tomcat9的NIO、NIO2、APR三种I/O模型的工作原理以及使用Jmeter对其进行持续压力测试。 1、connector的工作原理 这里我们说的Tomcat中三种不同的I/O模型主要指的是其连接器(connector)的工作模型,...
  • tomcat 性能优化压力测试

    千次阅读 2016-05-07 19:00:34
    压力测试工具:Loadrunner7.8。 负载平衡方案如下: 一台机器(操作系统2003)安装apache,作为负载服务器,并安装tomcat作为一个worker;一个单独安装tomcat,作为第二个worker;剩下的一台单独作为数据库服务器...
  • tomcat压力测试优化

    2010-01-21 00:00:00
    优化: 外部:JVM性能 操作系统性能 跟其他服务器整合 负载均衡 内部:禁止DNS查询 调整线程数 加速JSP编译速度:使用其他编译器 转载于:...
  • Tomcat优化 - 压力测试

    千次阅读 2010-09-30 13:30:00
    Tomcat和应用程序进行了压力测试后,如果您对应用程序的性能结果不太满意,就可以采取一些性能调整措施了,当然了前提是应用程序没有问题,我们这里只讲Tomcat的调整。由于Tomcat的运行依赖于JVM,所以在这里我们...
  • {"i18nChapterName": "章","i18nUnitName": "节","i18nLessonName": "课时","i18nTaskName":"任务"}{"text": {"icon": "es-icon es-icon-graphic","name": "图文"},"video": {"icon": "es-icon es-icon-video","name...
  • 本文主要使用jmeter工具对tomcat8进行压力测试,并使用java visualVM进行压测性能监控,通过监控数据调整tomcat参数 步入正题: 首先操作系统已优化完成,java版本为1.8以上,tomcat版本8.0.48,根据自己实际情况而定 ...
  • Tomcat6性能优化

    2021-08-02 08:22:15
    1.内存设置Windows环境下修改“%TOMCAT_HOME%\bin\catalina.bat”文件,在文件开头增加如下设置:set JAVA_OPTS=-Xms256m -Xmx512m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m-Xms设置初始化内存...
  • tomcat6 性能优化

    2017-09-16 11:23:21
    Tomcat和应用程序进行了压力测试后,如果您对应用程序的性能结果不太满意,就可以采取一些性能调整措施了,当然了前提是应用程序没有问题,我们这 里只讲Tomcat的调整。由于Tomcat的运行依赖于JVM,所以在这里我们...
  • 性能优化-Tomcat8优化

    2020-01-15 15:07:48
    1、Tomcat8优化 tomcat服务器在JavaEE项目中使用率非常高,所以在生产环境对tomcat优化也变得非常重要了。 对于tomcat优化,主要是从2个方面入手,一是,tomcat自身的配置,另一个是 tomcat所运行的jvm虚拟机的...
  • 而且优化后的Tomcat性能提升显著,本文从以下几方面进行分析优化。一、内存优化默认情况下Tomcat的相关内存配置较低,这对于一些大型项目显然是不够用的,这些项目运行就已经耗费了大部分内存空间,何况大规模访问的...
  • tomcat8 优化 tomcat可以说是比较常用的了,所以tomcat优化在生产环境也是比较重要的。对于tomcat优化,主要从2个方面,一是tomcat自身的配置,另外一个就是利用jvm虚拟机的调优。...然后利用 Jmeter 做压力测试。先...
  • 记一次压力测试引起的系统响应时间过长、Tomcat服务出现服务连接拒绝问题的排查和调优在行内做并发压力测试(300并发)的时候,我方系统出现了响应时间过长、Tomcat出现服务连接拒绝等问题 在行内做并发压力测试(300...
  • 今天我们来学习一个这个压力测试工具 是apache的产品 每当我们学习一个工具的时候 最应该想到的第一步就是 安装它了 windows 版本 linux 版本 会在后续 奉上~ 开发 安装地址 去下载 下载完毕之后解码 点击 readme_...
  • Tomcat优化详细教程

    万次阅读 多人点赞 2018-03-08 09:30:57
    而且优化后的Tomcat性能提升显著,本文从以下几方面进行分析优化。    一、内存优化  默认情况下Tomcat的相关内存配置较低,这对于一些大型项目显然是不够用的,这些项目运行就已经耗费了大部分内存空间...
  • Tomcat优化

    2019-10-21 14:44:57
    目录一: Tomcat内存优化 一: Tomcat内存优化 启动时告诉JVM我要一块大内存(调优内存是最直接的方式) Windows 下的catalina.bat Linux 下的catalina.sh 如: [root@instance-2bf2b6pr ~]# cd /opt/tomcat/apache-...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,930
精华内容 4,772
关键字:

tomcat压力测试优化