tomcat优化

1.内存分配
    Tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,需要调大。一般使用数据量较大的应用程序会使用持久对象,内存使用有可能迅速地增长。当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃。
考虑到生产环境有2个tomcat实例,建议分配1024m
修改内存等 JVM相关配置
         Linux 下修改TOMCAT_HOME/bin/catalina.sh,在其中加入
        #vim catalina.sh  //打开后会直接到目标行
         //在“cygwin=false”上面加入以下行:
JAVA_OPTS="-server -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxNewSize=512m"




        -server:启用 JDK的 server 版本;
        -Xms: Java 虚拟机初始化时堆的最小内存,一般与 Xmx配置为相同值,这样的好处是GC不必再为扩展内存空间而消耗性能;
        -Xmx: Java 虚拟机可使用堆的最大内存;
        -XX:PermSize:Java虚拟机永久代大小;
        -XX:MaxPermSize:Java虚拟机永久代大小最大值;

在停止Tomcat 的时候可能出现如下报错
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=128m; support was removed in 8.0Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0

使用JDK 8.0,把去掉PermSize和MaxPermSize两个参数设置去掉就可以了
JAVA_OPTS=”$JAVA_OPTS -server -Xms1024m -Xmx1024m”
2.服务启动优化
第一种方法 :修改Java
  打开$JAVA_PATH/jre/lib/security/java.security这个文件,找到下面的内容:
  securerandom.source=file:/dev/urandom (或者 securerandom.source=file:/dev/random)
  替换成
  securerandom.source=file:/dev/./ u random
  (这里加粗的u一定要带上)
  修改后结果: Server startup in 1904 ms
第二种方法 :修改/apache-tomcat-8.5.16/bin/catalina.sh  
  在catalina.sh中的 “#!/bin/sh” 下面添加如下代码:
if [[ "$JAVA_OPTS" != *-Djava.security.egd=* ]]; then JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"fi
  修改后的结果:  Server startup in 1899 ms
第三种方法 :添加环境变量 
在/etc/profile里添加环境变量:
    export JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"

vim /JAVA_HOME/jre/lib/security/java.security

3.配置优化
<Connector port= "8080"    
          protocol= "HTTP/1.1"    
          maxThreads= "1000"    
          minSpareThreads= "100"    
          acceptCount= "1000"   
          maxConnections= "1000"   
          connectionTimeout= "20000"    
          maxHttpHeaderSize= "8192"   
          tcpNoDelay= "true"   
          compression= "on"   
          compressionMinSize= "2048"   
          disableUploadTimeout= "true"   
          redirectPort= "8443"   
       enableLookups= "false"   
          URIEncoding= "UTF-8"  />  

         1)port: 代表Tomcat监听端口,也就是网站的访问端口,默认为8080,可以根据需要改成其他。
         2)protocol: 协议类型,可选类型有四种,分别为BIO(阻塞型IO),NIO,NIO2和APR。
        (1)BIO:BIO(Blocking I/O),顾名思义,即阻塞式I/O操作,表示Tomcat使用的是传统的 Java  I/O操作(即java.io包及其子包)。Tomcat在默认情况下,是以bio模式运行的。遗憾的是,就一般而言,bio模式是三种运行模式中性能最低的一种。BIO配置采用默认即可。
        (2)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)更好的并发运行性能。要让Tomcat以nio模式来运行也比较简单,我们只需要protocol类型修改为:
       (3)APR:APR(Apache Portable Runtime/Apache可移植运行时),是Apache HTTP服务器的支持库。你可以简单地理解为:Tomcat将以JNI的形式调用 Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地提高 Tomcat对静态文件的处理性能。 
         3)maxThreads: 由该连接器创建的处理请求线程的最大数目,也就是可以处理的同时请求的最大数目。如果未配置默认值为200。如果一个执行器与此连接器关联,则忽略此属性,因为该属性将被忽略,所以该连接器将使用执行器而不是一个内部线程池来执行任务。
        maxThreads是一个重要的配置属性,maxThreads配置的合理直接影响了Tomcat的相关性能,所以这里我们重点讨论下。
        maxThreads并不是配置的越大越好,事实上你即使配置成999999也是没有用的,因为这个最大值是受 操作系统 及相关硬件所制约的,并且最大值并不一定是最优值,所以我们追寻的应该是最优值而不是最大值。
         QPS (Query Per Second):每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。我们常常使用 QPS值来衡量一个服务器的性能。
        QPS = 并发数 / 平均响应时间
        或者
        并发数 = QPS * 平均响应时间
        一个系统吞吐量通常由QPS、并发数两个因素决定,每套系统的这两个值都有一个相对极限值,在应用场景访问压力下,只要某一项达到系统最高值,系统的吞吐量就上不去了,如果压力继续增大,系统的吞吐量反而会下降,原因是系统超负荷工作,上下文切换、内存等等其它消耗导致系统性能下降。所谓吞吐量这里可以理解为每秒能处理请求的次数。
        所以选择一个合理的 maxThreads值,其实并不是那么容易的事。因为过多的线程只会造成,更多的内存开销,更多的CPU开销,但是对提升QPS确毫无帮助;找到最佳线程数后通过简单的设置,可以让web系统更加稳定,得到最高,最稳定的QPS输出。
        我们可以通过以下几种方式来获取 maxThreads的最佳值:
        (1)通过线上系统不断使用和用户的不断增长来进行性能 测试 ,观察QPS,响应时间,这种方式会在爆发式增长时系统崩溃,如双12等。
        (2)根据公式计算,服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量,这种方式有时会被误导,因为某些系统处理环节可能会耗时比较长,从而影响公式的结果。
        (3)单、多用户压力测试,查看CPU的消耗,然后直接乘以百分比,再进行压测,一般这个值的附近应该就是最佳线程数量,这种方式理想场景比较适用,实际情况会比这个复杂的多。
        (4)根据系统的自身情况调整,如硬件限制,系统限制,程序处理能力限制等。
        (5)定期修改为不同的 maxThreads值,看服务器响应结果及用户反应。
         QPS和线程数的关系
        (1)在最佳线程数量之前,QPS和线程是互相递增的关系,线程数量到了最佳线程之后,QPS持平,不在上升,甚至略有下降,同时相应时间持续上升。
        (2)同一个系统而言,支持的线程数越多(最佳线程数越多而不是配置的线程数越多),QPS越高。
         QPS和响应时间的关系
        (1)对于一般的web系统,响应时间一般有CPU执行时间+IO等待时间组成。
        (2)CPU的执行时间减少,对QPS有实质的提升,IO时间的减少,对QPS提升不明显。如果要想明显提升QPS,优化系统的时候要着重优化CPU消耗大户。
        所以想要找出 maxThreads的最优值可并不容易,没有最好只有更好,更好的值只能通过时间来显现,如果你不想考虑那么多,一般情况下设置成1000即可。
         4)minSpareThreads: 线程的最小运行数目,这些始终保持运行。如果未指定,默认值为10。
         5)acceptCount: 当所有可能的请求处理线程都在使用时传入连接请求的最大队列长度。如果未指定,默认值为100。一般是设置的跟 maxThreads一样或一半,此值设置的过大会导致排队的请求超时而未被处理。所以这个值应该是主要根据应用的访问峰值与平均值来权衡配置。
         6)maxConnections: 在任何给定的时间内,服务器将接受和处理的最大连接数。当这个数字已经达到时,服务器将接受但不处理,等待进一步连接。NIO与NIO2的默认值为10000,APR默认值为8192。
         7)connectionTimeout: 当请求已经被接受,但未被处理,也就是等待中的超时时间。单位为毫秒,默认值为60000。通常情况下设置为30000。
        8)maxHttpHeaderSize: 请求和响应的HTTP头的最大大小,以字节为单位指定。如果没有指定,这个属性被设置为8192(8 KB)。
         9)tcpNoDelay: 如果为true,服务器socket会设置TCP_NO_DELAY选项,在大多数情况下可以提高性能。缺省情况下设为true。
        10)compression: 是否启用gzip压缩,默认为关闭状态。这个参数的可接受值为“off”(不使用压缩),“on”(压缩文本数据),“force”(在所有的情况下强制压缩)。
         11)compressionMinSize: 如果compression="on",则启用此项。被压缩前数据的最小值,也就是超过这个值后才被压缩。如果没有指定,这个属性默认为“2048”(2K),单位为byte。
         12)disableUploadTimeout: 这个标志允许servlet  Container 在一个servlet执行的时候,使用一个不同的,更长的连接超时。最终的结果是给servlet更长的时间以便完成其执行,或者在数据上载的时候更长的超时时间。如果没有指定,设为false。
         13)enableLookups: 关闭DNS反向查询。
         14)URIEncoding: URL编码字符集。




4dump包生成

  OutOfMemoryError,内存不足
内存泄露
线程死锁
锁争用(Lock Contention)
java进程消耗CPU过高
     这些问题在日常开发中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深究问题根源),但能够理解并解决这些问题是Java程序员进阶的必备要求。本文将对一些常用的JVM性能调优监控工具hprof进行介绍。
二、 hprof文件的生成
       生成hprof文件可以在DDMS(DDMS  的全称是 DalvikDebug Monitor Service ,是  Android  开发环境中的 Dalvik 虚拟机调试监控服务。提供测试设备截屏、查看特定进程正在运行的线程以及堆信息、 Logcat 、广播状态信息、模拟电话呼叫、模拟接收及发送 SMS 、虚拟地理坐标等服务 )选中进程点击窗口左上角的"dump hprof file"按钮来直接生成,也可以通过在程序加代码中来生成,以下通过设置生成hprof文件:
       我们希望在memory 溢出时候能自动生成heap dump文件,为此,我们在运行时候添加JVM 参数: 
        -XX:+HeapDumpOnOutOfMemoryError
注:dump生成的.hprof文件默认放到了该项目目录下面。
  先构造一个实体类User,这个User类就是一般的java 类,然后我们构造一个ArrayList,然后在一个无限循环中一直放这个User类的实例,因为User类和ArrayList都在堆上,而ArrayList因为是强引用,所以无法被GC回收,(因为我们List一直在用并没有摧毁)所以一旦ArrayList所占用的堆内存填满整个heap size时候,heap就溢出了。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值