tomcat参数优化

Tomcat并发优化

参考及部分来源:tomcat8.0 基本参数调优配置, 普通但有效的JVM参数和命令, 配个GC日志呗,不然咋分析故障原因

  • Tomcat配置文件server.xml中

    minProcessors:		最小空闲连接线程数,用于提高系统处理性能,默认值为 10
    maxProcessors:		最大连接线程数,即:并发处理的最大请求数,默认值为 75
    acceptCount:		允许的最大连接数,应大于等于 maxProcessors ,默认值为 100
    enableLookups:		是否反查域名,取值为: true 或 false,为了提高处理能力,应设置为false
    connectionTimeout:	网络连接超时,单位:毫秒。设置为 0 表示永不超时,这样设置有隐患的。通常可设置为 30000 毫秒,其中和最大连接数相关的参数为maxProcessors 和 acceptCount 。如果要加大并发连接数,应同时加大这两个参数。
    web server允许的最大连接数还受制于操作系统的内核参数设置,通常 Windows 是 2000 个左右, Linux 是 1000 个左右。 
    
    maxThreads:			客户请求最大线程数
    minSpareThreads:	Tomcat初始化时创建的 socket 线程数
    maxSpareThreads:	Tomcat连接器的最大空闲 socket 线程数
    redirectPort:		在需要基于安全通道的场合,把客户请求转发到基于SSL 的 redirectPort 端口
    acceptAccount:		监听端口队列最大数,满了之后客户请求会被拒绝 (不能小于maxSpareThreads)
    URIEncoding:		URL统一编码
    
  • 正常配置

    <Connector port="8080" protocol="HTTP/1.1"
               maxSwallowSize="-1"
               maxThreads="1000"
               minProcessors="100"
               maxProcessors="1000"
               minSpareThreads="100"
               maxSpareThreads="1000"
               enableLookups="false"
               URIEncoding="utf-8"
               acceptCount="1000"
               connectionTimeout="20000"
               disableUploadTimeout="ture"
               proxyPort="8443"
               redirectPort="8443" />
    

jvm内存调优

  • java启动参数共分为三类
    • 其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容
    • 其二是非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容
    • 其三是非Stable参数(-XX),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用

调试参数

  • 打印启动参数:

    可以查看默认参数
    	java -XX:+PrintCommandLineFlags -version
    
    ]# java -XX:+PrintCommandLineFlags -version
    -XX:InitialHeapSize=111329088 -XX:MaxHeapSize=1781265408 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops 
    openjdk version "1.8.0_181"
    OpenJDK Runtime Environment (build 1.8.0_181-b13)
    OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
    
  • 打印ClassLoader日志

    这个参数会在控制台打印所有类加载/卸载信息
    	-XX:+TraceClassLoading -XX:+TraceClassUnloading
    
  • OOM时Dump内存

    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/crashes/my-heap-dump.hprof
    
    # OOM时执行脚本(比如重启,参考)
    -XX:OnOutOfMemoryError=/scripts/restart-myapp.sh
    

内存类

  • JVM设置内存的单位默认是字节

    -Xmn256m
    -Xmn262144k
    -Xmn268435456
    
  • 设置初始新生代大小-XX:NewSize=2G(也可以是2M)

  • 设置最大新生代大小: -XX:MaxNewSize=2G(也可以是2M)

    • 注意:-Xmn优先级大于-XX:NewRatio
  • 设置Eden/Survivor比例

    • 表示两个Survivor和Edgen区的比,8表示两个Survivor:Eden=2:8,即一个Survivor占新生代的1/10。

      # 计算方式为:
      Survivor Size(1) = Young Generation Size / (2+<SurvivorRatio)
      Eden Size = Young Generation Size / (2+SurvivorRatio) * SurvivorRatio
      
    • 配置:-XX:SurvivorRatio=8

  • 设置老年代大小

    • 老年代大小无法直接设置,只能通过堆大小+分配比例进行调整 `` #设置新老一代大小之间的比率。默认值为2。2表示New Size:Old Size=1:2,则新生代占堆大小的1/3,老年代占堆大小的2/3

      # 计算方式为:
          New Size = Heap Size / NewRatio + 1
          Old Size = (Heap Size / NewRatio + 1) * NewRatio
      
    • 配置: -XX:NewRatio=2

  • 设置永久代(PermGen/MetaSpace)大小

    #设置分配的Metaspace的大小,Metaspace将在首次超过垃圾收集时触发垃圾收集。 垃圾收集的阈值取决于使用的元数据量而增加或减少。 默认大小取决于平台。
    -XX:MetaspaceSize=size
    
    #设置可以分配给Metaspace的最大本机内存。 默认情况下,大小不受限制。 应用程序的Metaspace量取决于应用程序本身,其他正在运行的应用程序以及系统上可用的内存量
    -XX:MaxMetaspaceSize=size
    

调优典型设置

  • java -Xmx3550m -Xms3550m -Xmn2g -Xss128k

    1. -Xmx3550m:设置JVM最大可用内存为3550M。
    2. -Xms3550m:设置JVM促使内存为3550m。此值可以设置与 -Xmx 相同,以避免每次垃圾回收完成后JVM重新分配内存。
    3. -Xmn2g:设置年轻代大小为2G。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
    4. -Xss128k:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
  • java -Xmx3550m -Xms3550m -Xss128k -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxPermSize=16m -XX:MaxTenuringThreshold=0

    1. -XX:NewRatio=4:设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
    2. -XX:SurvivorRatio=4:设置年轻代中Eden区与Survivor区的大小比值。设置为4,则两个Survivor区与一个Eden区的比值为2:4,一个Survivor区占整个年轻代的1/6
    3. -XX:MaxPermSize=16m:设置持久代大小为16m。
    4. -XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。

gc调优

打印内容

  • 打印对象分布

    • 分析 GC 时的晋升情况和晋升导致的高暂停: -XX:+PrintTenuringDistribution

    • 输出内容示例

      Desired survivor size 59244544 bytes, new threshold 15 (max 15)
      - age   1:     963176 bytes,     963176 total
      - age   2:     791264 bytes,    1754440 total
      - age   3:     210960 bytes,    1965400 total
      - age   4:     167672 bytes,    2133072 total 
      
  • GC 后打印堆数据

    每次发生 GC 时,对比一下 GC 前后的堆内存情况,更直观
    	-XX:+PrintHeapAtGC
    
  • 打印基本 GC 信息

    • 打印 GC 日志参数: -XX:+PrintGCDetails -XX:+PrintGCDateStamps

    • 输出内容示例

      {Heap before GC invocations=0 (full 0):
       garbage-first heap   total 1024000K, used 324609K [0x0000000781800000, 0x0000000781901f40, 0x00000007c0000000)
        region size 1024K, 6 young (6144K), 0 survivors (0K)
       Metaspace       used 3420K, capacity 4500K, committed 4864K, reserved 1056768K
        class space    used 371K, capacity 388K, committed 512K, reserved 1048576K
      Heap after GC invocations=1 (full 1):
       garbage-first heap   total 1024000K, used 21755K [0x0000000781800000, 0x0000000781901f40, 0x00000007c0000000)
        region size 1024K, 0 young (0K), 0 survivors (0K)
       Metaspace       used 3420K, capacity 4500K, committed 4864K, reserved 1056768K
        class space used 371K, capacity 388K, committed 512K, reserved 1048576K
      }
      
  • 打印 STW 时间

    暂停时间是 GC 最重要的指标
    	-XX:+PrintGCApplicationStoppedTime
    
    Total time for which application threads were stopped: 0.0254260 seconds, Stopping threads took: 0.0000218 seconds
    
  • 打印 safepoint 信息

    • 进入STW阶段之前,需要要找到一个合适的 safepoint ,这个指标一样很重要(非必选,出现 GC 问题时最好加上此参数调试)

      -XX:+PrintSafepointStatistics -XX:PrintSafepointStatisticsCount=1
      
    • 输出内容示例

      vmop [threads: total initially_running wait_to_block]    [time: spin block sync cleanup vmop] page_trap_count
      0.379: ParallelGCSystemGC
      [ 10  0  0  ]  [  0  0  0  0  16  ]  0    
      
  • 打印 Reference 处理信息

    • 强引用/弱引用/软引用/虚引用/finalize 方法问题: -XX:+PrintReferenceGC

    • 输出内容示例

      2021-02-19T12:41:30.462+0800: 5072726.605: [SoftReference, 0 refs, 0.0000521 secs]
      2021-02-19T12:41:30.462+0800: 5072726.605: [WeakReference, 0 refs, 0.0000069 secs]
      2021-02-19T12:41:30.462+0800: 5072726.605: [FinalReference, 0 refs, 0.0000056 secs]
      2021-02-19T12:41:30.462+0800: 5072726.605: [PhantomReference, 0 refs, 0 refs, 0.0000059 secs]
      2021-02-19T12:41:30.462+0800: 5072726.605: [JNI Weak Reference, 0.0000131 secs], 0.4635293 secs]
      
  • 完整参数

    # requireds
    -XX:+PrintGCDetails
    -XX:+PrintGCDateStamps
    -XX:+PrintTenuringDistribution
    -XX:+PrintHeapAtGC
    -XX:+PrintReferenceGC
    -XX:+PrintGCApplicationStoppedTime
    
    # optional
    -XX:+PrintSafepointStatistics
    -XX:PrintSafepointStatisticsCount=1
    

输出方式

  • JVM提供了几个用于分割 GC 日志的参数:

    # GC日志输出的文件路径
    -Xloggc:/path/to/gc.log
    
    # 开启日志文件分割
    -XX:+UseGCLogFileRotation 
    
    # 最多分割几个文件,超过之后从头开始写
    -XX:NumberOfGCLogFiles=14
    
    # 每个文件上限大小,超过就触发分割
    -XX:GCLogFileSize=100M
    
    • -Xloggc 方式指定的日志文件,是覆盖写的方式,每次启动都会覆盖,历史日志会丢失
    • 当超过最大分割数后,会从第0个文件开始重新写入,而且是覆盖
    • -XX:NumberOfGCLogFiles 并不能设置为无限
    • **问题:**这个覆盖就有点恶心了,每次启动都会覆盖之前的历史日志
  • 使用时间戳命名文件

    # GC日志输出的文件路径
    -Xloggc:/path/to/gc-%t.log
    # 开启日志文件分割
    -XX:+UseGCLogFileRotation 
    # 最多分割几个文件,超过之后从头开始写
    -XX:NumberOfGCLogFiles=14
    # 每个文件上限大小,超过就触发分割
    -XX:GCLogFileSize=100M
    

gc典型设置

# 必备
-XX:+PrintGCDetails 
-XX:+PrintGCDateStamps 
-XX:+PrintTenuringDistribution 
-XX:+PrintHeapAtGC 
-XX:+PrintReferenceGC 
-XX:+PrintGCApplicationStoppedTime

# 可选
-XX:+PrintSafepointStatistics 
-XX:PrintSafepointStatisticsCount=1

# GC日志输出的文件路径
-Xloggc:/path/to/gc-%t.log
# 开启日志文件分割
-XX:+UseGCLogFileRotation
# 最多分割几个文件,超过之后从头文件开始写
-XX:NumberOfGCLogFiles=14
# 每个文件上限大小,超过就触发分割
-XX:GCLogFileSize=100M

tomcat-gc处理

-server -Xmn2048M -Xms5120M -Xmx5120M -Dfile.encoding=UTF-8 -XX:SurvivorRatio=8 -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=2048m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:\gc\heap\gc.hprof -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:d:\gc\heap\gc.log"
-server -Xmn2730M -Xms8192M -Xmx8192M -XX:-UseLargePages -XX:SurvivorRatio=8 -Dfile.encoding=UTF-8 -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=512m -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/java_heapdump.hprof -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Xloggc:/data/gm_gc.log

你可能感兴趣的:(linux,tomcat,jvm,java)