tomcat和iis的区别(tomcat和iis是干什么的)

技能目标:

· 了解Tomcat

· 熟悉Tomcat多虚拟主机环境

· 会使用jmeter工具

· 会优化Tomcat

· 能处理常见错误

11.1 案例分析

11.1.1 案例概述

自2017年11月编程语言排行榜Java占比13%,高居榜首,Tomcat也一度成为Java开发人员的首选。其开源、占用系统资源少、跨平台等特性被深受喜爱。本章主要学习如何部署Tomcat服务,根据生产环境实现多个虚拟主机的配置,最后的重点是进行压测,根据压测结果如何优化Tomcat服务及常见的内存溢出如何处理。

11.1.2 案例前置知识点

1. Tomcat介绍

自从JSP发布之后,推出了各式各样的JSP引擎。Apache Group在完成GNUJSP1.0的开发以后,开始考虑在SUN的JSWDK基础上开发一个可以直接提供Web服务的JSP服务器,当然同时也支持Servlet, 这样Tomcat就诞生了。

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。其被JavaWorld杂志的编辑选为2001年度最具创新的Java产品,同时它又是sun公司官方推荐的Servlet和JSP容器,因此其越来越多的受到软件公司和开发人员的喜爱。由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上,Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当运行Tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。

当配置正确时,Apache 为HTML页面服务,而Tomcat 实际上运行JSP 页面和Servlet。另外,Tomcat和IIS等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache服务器。

2. Tomcat核心组件

通常意义上的Web服务器接受请求后,只是单纯地响应静态资源,如HTML文件,图片文件等,不能在后端进行一定的处理操作。 Tomcat是Apache下的一个子项目,它具备Web服务器的所有功能,不仅可以监听接受请求并响应静态资源,而且可以在后端运行特定规范的Java代码Servlet,同时将执行的结果以HTML代码的形式写回客户端。 Tomcat由一系列的组件构成,其中核心的组件有三个: 1)Web容器:完成Web服务器的功能。 2)Servlet容器:名字为catalina,用于处理Servlet代码。 3)JSP容器:用于将JSP动态网页翻译成Servlet代码。

3. Tomcat处理请求过程

1) 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/11.1 Connector获得。 2) Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应。

3) Engine获得请求localhost/yy/index.JSP,匹配它所拥有的所有虚拟主机Host。 4) Engine匹配到名为localhost的Host。即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机。 5) localhost Host获得请求/yy/index.JSP,匹配它所拥有的所有Context。 6) Host匹配到路径为/yy的Context。如果匹配不到,就把该请求交给路径名为””的Context去处理。 7) path=”/yy”的Context获得请求/index.JSP,在它的mapping table中寻找对应的Servlet。 8) Context匹配到URL PATTERN为*.JSP的Servlet,对应于JSPServlet类。

9) 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JSPServlet的doGet()或doPost()方法。

10)Context把执行完了之后的HttpServletResponse对象返回给Host。 11)Host把HttpServletResponse对象返回给Engine。 12)Engine把HttpServletResponse对象返回给Connector 。13)Connector把HttpServletResponse对象返回给客户browser。

11.1.3 案例环境

1. 本案例实验环境

tomcat和iis的区别(tomcat和iis是干什么的)

表11-1 案例的实验环境

2. 案例需求

1)部署Tomcat服务。

2)配置虚拟主机。

3)Tomcat优化。

4)常见错误分析及处理。

3. 案例实现思路

1)安装Tomcat需要的环境。

2)安装Tomcat服务。

3)配置虚拟主机。

4)客户端安装压测软件进行压测并调优。

5)常见错误说明。

11.2 案例实施

11.2.1 下载并安装JDK

1. 在部署Tomcat之前必须安装好jdk,因为jdk是Tomcat运行的必要环境。而jdk的安装也相对比较简单,版本有很多,这里我们选择rpm版本即可!打开oracle官网http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html,该网页中会有172的大版本。根据所使用的计算机硬件配置,选择其中一个安装包,如图11.1所示。本章,选择基于linux64位rpm版本,必须选中Accept License Agreement再进行下载。

tomcat和iis的区别(tomcat和iis是干什么的)

图11.1

2. 下载完安装包后,将其上传到服务器/root目录下,执行安装命令:

[root@localhost ~]# rpm -ivh jdk-8u171-linux-x64.rpm

准备中… ################################# [100%]

正在升级/安装…

1:jdk1.8-2000:1.8.0_171-fcs ################################# [100%]

Unpacking JAR files…

tools.jar…

plugin.jar…

javaws.jar…

deploy.jar…

rt.jar…

jsse.jar…

charsets.jar…

localedata.jar…

3. 上面显示安装完成,jdk安装目录在/usr/java/jdk1.8.0_171-amd64,设置jdk的环境变量,编辑/etc/profile文件,增加如下内容:

[root@localhost ~]# vim /etc/profile

export JAVA_HOME=/usr/java/jdk1.8.0_171-amd64

export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar

export PATH=$JAVA_HOME/bin:$PATH

4. 使环境变量生效:

[root@localhost ~]# source /etc/profile

5. 查看jdk版本号,已经显示是我们安装的软件版本:

[root@localhost ~]# java -version

java version “1.8.0_171”

Java(TM) SE Runtime Environment (build 1.8.0_171-b11)

Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)

11.2.2 安装启动Tomcat

1. 执行下面的命令,从Tomcat官网下载apache-tomcat-9.0.8.tar.gz稳定版本:

[root@localhost ~]# wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.8/bin/apache-tomcat-9.0.8.tar.gz

2. 将安装包移动Tomcat目录到/usr/local下面:

[root@localhost ~]# tar zxf apache-tomcat-9.0.8.tar.gz

[root@localhost ~]# mv apache-tomcat-9.0.8 /usr/local/tomcat

3. 启动Tomcat:

[root@localhost ~]# /usr/local/tomcat/bin/startup.sh

Using CATALINA_BASE: /usr/local/tomcat

Using CATALINA_HOME: /usr/local/tomcat

Using CATALINA_TMPDIR: /usr/local/tomcat/temp

Using JRE_HOME: /usr/java/jdk1.8.0_171-amd64

Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar

Tomcat started.

浏览器打开http://192.168.9.236:8080进行访问会出现Tomcat主页,如图11.2所示。

tomcat和iis的区别(tomcat和iis是干什么的)

图11.2

4. 相信大家第一次启动查看日志会发现Tomcat启动很慢,默认情况下都需要几十秒,可以修改jdk参数进行改善,打开/usr/java/jdk1.8.0_171-amd64/jre/lib/security/java.security文件,找到如下内容:securerandom.source=file:/dev/random修改成securerandom.source=file:/dev/urandom。

[root@localhost conf]# vim /usr/java/jdk1.8.0_171-amd64/jre/lib/security/java.security

securerandom.source=file:/dev/urandom

[root@localhost conf]# /usr/local/tomcat/bin/shutdown.sh//关闭Tomcat

Using CATALINA_BASE: /usr/local/tomcat

Using CATALINA_HOME: /usr/local/tomcat

Using CATALINA_TMPDIR: /usr/local/tomcat/temp

Using JRE_HOME: /usr/java/jdk1.8.0_171-amd64

Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar

[root@localhost conf]# /usr/local/tomcat/bin/startup.sh //启动Tomcat

Using CATALINA_BASE: /usr/local/tomcat

Using CATALINA_HOME: /usr/local/tomcat

Using CATALINA_TMPDIR: /usr/local/tomcat/temp

Using JRE_HOME: /usr/java/jdk1.8.0_171-amd64

Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar

Tomcat started.

然后,重启Tomcat就会发现启动时间变短了很多。

5. 查看Tomcat安装后目录结构,如下图11.3所示:

tomcat和iis的区别(tomcat和iis是干什么的)

图11.3

下面,对每个目录进行说明。

1)bin

存放启动和关闭Tomcat的脚本文件,比较常用的是catalina.sh、startup.sh、shutdown.sh三个文件。

2)conf

存放Tomcat服务器的各种配置文件,比较常用的是server.xml、context..xml、tomcat-users.xml、web.xml四个文件。

3)lib

存放Tomcat服务器的jar包,一般不作任何改动,除非连接第三方服务,比如redis,那就需要添加相对应的jar包。

4)logs

存放Tomcat日志。

5)temp

存放Tomcat运行时产生的文件。

6)webapps

存放项目资源的目录。

7)work

Tomcat工作目录,一般清除Tomcat缓存的时候会使用到。

11.2.3 虚拟主机配置

可能有时候公司会有多个项目需要运行,那么肯定不可能是一台服务器上运行多个Tomcat服务,这样会消耗太多的系统资源。此时,就需要使用到Tomcat虚拟主机。例如现在新增两个域名www.test.com和bbs.test.com,希望通过这两个域名访问到不同的项目内容。

1. 创建www和bbs项目目录和文件

执行下面的命令,可以创建www和bbs项目目录和文件。

[root@localhost ~]# mkdir /usr/local/tomcat/webapps/www

[root@localhost ~]# echo “This is www page\!” > /usr/local/tomcat/webapps/www/index.jsp

[root@localhost ~]# mkdir /usr/local/tomcat/webapps/bbs

[root@localhost ~]# echo “This is bbs page\!” > /usr/local/tomcat/webapps/bbs/index.jsp

2. 修改Tomcat主配置文件

修改Tomcat主配置文件/usr/local/tomcat/conf/server.xml,在</Host>下面增加如下内容:

//关于www.test.com的虚拟主机配置

<Host name=”www.test.com” appBase=”/usr/local/tomcat/webapps”

unpackWARs=”true” autoDeploy=”true” xmlValidation=”false”

xmlNamespaceAware=”false”>

<Context docBase=”/usr/local/tomcat/webapps/www”

path=”” reloadable=”true” />

</Host>

//关于bbs.test.com的虚拟主机配置

<Host name=”bbs.test.com” appBase=”/usr/local/tomcat/webapps”

unpackWARs=”true” autoDeploy=”true” xmlValidation=”false”

xmlNamespaceAware=”false”>

<Context docBase=”/usr/local/tomcat/webapps/bbs”

path=”” reloadable=”true” />

</Host>

[root@localhost ~]# /usr/local/tomcat/bin/shutdown.sh

[root@localhost ~]# /usr/local/tomcat/bin/startup.sh

3. 测试

客户端绑定两个域名需要写入本机hosts,Tomcat默认端口是8080。

192.168.9.236 www.test.com

192.168.9.236 bbs.test.com

使用浏览器访问http://www.test.com:8080,页面效果如图11.4所示。

tomcat和iis的区别(tomcat和iis是干什么的)

图11.4

使用浏览器访问http://bbs.test.com:8080,页面效果如图11.5所示。

tomcat和iis的区别(tomcat和iis是干什么的)

图11.5

11.2.4 Tomcat优化

Tomcat 的缺省配置并不适合生产环境,它会频繁出现假死现象需要重启,只有通过不断压测优化才能让它最高效率稳定的运行。优化主要有三方面,分为操作系统优化(内核参数优化),Tomcat 配置文件参数优化,Java 虚拟机(JVM)调优。其中最难理解的就是jvm调优。系统优化本章不介绍,本章将配合jmeter压测工具进行调优前和调优后的数据进行比较。

1. Tomcat配置文件参数优化

关于Tomcat主配置文件server.xml里面很多默认的配置项,但并不能满足业务需求,常用的优化相关参数如下。

1)maxThreads:Tomcat 使用线程来处理接收的每个请求,这个值表示Tomcat可创建的最大的线程数,默认值是200。

2)minSpareThreads:最小空闲线程数,Tomcat 启动时的初始化的线程数,表示即使没有人使用也开这么多空线程等待,默认值是 10。

3)maxSpareThreads:最大备用线程数,一旦创建的线程超过这个值,Tomcat 就会关闭不再需要的 socket 线程。默认值是-1(无限制)。一般不需要指定。

4)URIEncoding:指定 Tomcat 容器的 URL 编码格式,语言编码格式这块倒不如其它 Web 服务器软件配置方便,需要分别指定。

5)connnectionTimeout:网络连接超时,单位:毫秒,设置为0表示永不超时,这样设置有隐患的。通常默认20000毫秒就可以。

6) enableLookups:是否反查域名,以返回远程主机的主机名,取值为:true 或 false,如果设置为false,则直接返回IP地址,为了提高处理能力,应设置为 false。

disableUploadTimeout:上传时是否使用超时机制。应设置为true。

8) connectionUploadTimeout:上传超时时间,毕竟文件上传可能需要消耗更多的时间,这个根据你自己的业务需要自己调,以使Servlet有较长的时间来完成它的执行,需要与上一个参数一起配合使用才会生效。

9)acceptCount:指定当所有可以使用的处理请求的线程数都被使用时,可传入连接请求的最大队列长度,超过这个数的请求将不予处理,默认为100个。

10)compression:是否对响应的数据进行 GZIP 压缩,off:表示禁止压缩;on:表示允许压缩(文本将被压缩)、force:表示所有情况下都进行压缩,默认值为off,压缩数据后可以有效的减少页面的大小,一般可以减小1/3左右,节省带宽。

11)compressionMinSize:表示压缩响应的最小值,只有当响应报文大小大于这个值的时候才会对报文进行压缩,如果开启了压缩功能,默认值就是2048。

compressableMimeType:压缩类型,指定对哪些类型的文件进行数据压缩。

13)noCompressionUserAgents=”gozilla, traviata”:对于以下的浏览器,不启用压缩。

如果已经对代码进行了动静分离,静态页面和图片等数据就不需要Tomcat 处理了,那么也就不需要在Tomcat 中配置压缩了。因为这里只有一台Tomcat服务器,而且压测的是Tomcat首页,会有图片和静态资源文件,所以这里启用压缩。

以上是一些常用的配置参数,还有好多其它的参数设置,还可以继续深入的优化,HTTP Connector 与 AJP Connector 的参数属性值,可以参考官方文档的详细说明进行学习。链接地址http://tomcat.apache.org/tomcat-9.0-doc/config/http.html,下面开始对Tomcat配置文件优化进行前后的对比。

要压测,首先学习关于jmeter压测工具基本的使用方法。执行步骤如下:

1)客户端安装jdk,可以从Oracle官方下载,安装过程直接下一步即可!

2)运行jmeter软件,如题11.6所示。

tomcat和iis的区别(tomcat和iis是干什么的)

图11.6

3)打开压测脚本进行压测,点击左上角文件->打开->选择压测脚本,如图11.7所示。

tomcat和iis的区别(tomcat和iis是干什么的)

图11.7

4.点击打开按钮,点击第一排绿色三角按钮(鼠标指上去后会显示启动)开始进行压测,如图11.8所示。

tomcat和iis的区别(tomcat和iis是干什么的)

图11.8

压测脚本里设置的是20秒启动4000个线程数,并发为2000,超时时间是50000毫秒。也可以适当的根据自己的需求进行修改。为了不那么复杂,从压测结果看只关注聚合报告,聚合报告只关注Average、90% Line、Error%这三列,因为压测Tomcat首页压力不会太大,所以Error都是为0属于正常。先看一组优化前(默认的配置)压测截图,如图11.9所示。

tomcat和iis的区别(tomcat和iis是干什么的)

图11.9

5. 打开Tomcat主配置文件server.xml,找到默认配置:

<Connector port=”8080″ protocol=”HTTP/11.1″

connectionTimeout=”20000″

redirectPort=”8443″ />

将默认配置做修改:

<Connector port=”8080″ protocol=”HTTP/11.1″

connectionTimeout=”20000″

redirectPort=”8443″ minSpareThreads=”50″

enableLookups=”false” disableUploadTimeout=”true”

acceptCount=”300″ maxThreads=”500″ processorCache=”500″

URIEncoding=”UTF-8″

compression=”on”

compressionMinSize=”2048″

compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plain,image/gif,image/jpg,image/png”/>

6. 重新启动Tomcat服务器,jmeter还是继续保持同样的参数进行压测,优化后压测截图,如11.10所示。

tomcat和iis的区别(tomcat和iis是干什么的)

图11.10

从结果看优化后的平均值和90%响应时间比优化前的快。

2. JVM优化

Tomcat 启动命令行中的优化参数,就是 JVM 的优化 。Tomcat 首先跑在 JVM 之上的,因为它的启动其实也只是一个Java命令行,首先我们需要对这个Java的启动命令行进行调优。不管是YGC还是Full GC、GC都会导致程序运行中断,正确的选择不同的GC策略,调整JVM、GC的参数,可以极大的减少由于GC工作而导致的程序运行中断方面的问题,进而适当的提高 Java程序的工作效率。但是调整GC是以个极为复杂的过程,由于各个程序具备不同的特点,如Web和GUI程序就有很大区别(Web可以适当的停顿,但GUI停顿是客户无法接受的),而且由于跑在各个机器上的配置不同(主要 CPU个数,内存不同),所以使用的 GC 种类也会不同。下面对JVM 参数做比较详细的说明。

Tomcat 的启动参数位于安装目录 ${JAVA_HOME}/bin目录下,Linux操作系统就是 catalina.sh 文件。Java_OPTS就是用来设置JVM 相关运行参数的变量,下面具体看JVM常用参数详解。

-server:一定要作为第一个参数,只要Tomcat是运行在生产环境中,这个参数必须给加上,不然后面的参数不会生效 。

-Xms:表示Java初始化堆的大小,-Xms与-Xmx设成一样的值,避免JVM反复重新申请内存,导致性能大起大落,默认值为物理内存的1/64,默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到 -Xmx 的最大限制。

-Xmx:表示最大Java堆大小,当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃,因此一般建议堆的最大值设置为物理内存的最大值的50%。

-XX:NewSize:设置新生代内存大小。

-XX:MaxNewSize:设置最大新生代新生代内存大小。

-XX:PermSize:设置持久代内存大小。

-XX:MaxPermSize:设置最大值持久代内存大小,永久代不属于堆内存,堆内存只包含新生代和老年代。

XX:+AggressiveOpts:作用如其名(aggressive),启用这个参数,则每当JDK版本升级时,你的JVM都会使用最新加入的优化技术(如果有的话)。

-XX:+UseBiasedLocking:启用一个优化了的线程锁,我们知道在我们的appserver,每个http请求就是一个线程,有的请求短有的请求长,就会有请求排队的现象,甚至还会出现线程阻塞,这个优化了的线程锁使得你的appserver内对线程处理自动进行最优调配。

-XX:+DisableExplicitGC:在 程序代码中不允许有显示的调用”System.gc()”。每次在到操作结束时手动调用 System.gc() 一下,付出的代价就是系统响应时间严重降低,就和关于 Xms,Xmx 里的解释的原理一样,这样去调用GC导致系统的JVM大起大落。

-XX:+UseParNewGC:对新生代采用多线程并行回收,这样收得快,注意最新的JVM 版本,当使用 -XX:+UseConcMarkSweepGC 时,-XX:UseParNewGC 会自动开启。因此,如果年轻代的并行GC不想开启,可以通过设置 -XX:-UseParNewGC 来关掉。

-XX:MaxTenuringThreshold:设置垃圾最大年龄。如果设置为0的话,则新生代对象不经过 Survivor 区,直接进入老年代。对于老年代比较多的应用(需要大量常驻内存的应用),可以提高效率。如果将此值设置为一 个较大值,则新生代对象会在 Survivor 区进行多次复制,这样可以增加对象在新生代的存活时间,增加在新生代即被回收的概率,减少Full GC的频率,这样做可以在某种程度上提高服务稳定性。该参数只有在串行 GC 时才有效,这个值的设置是根据本地的 jprofiler 监控后得到的一个理想的值,不能一概而论原搬照抄。

-XX:+CMSParallelRemarkEnabled:在使用 UseParNewGC 的情况下,尽量减少 mark 的时间。

-XX:+UseCMSCompactAtFullCollection:在使用concurrent gc的情况下,防止 memoryfragmention,对live object进行整理,使memory碎片减少。

-XX:LargePageSizeInBytes:指定 Java heap 的分页页面大小,内存页的大小不可设置过大, 会影响Perm的大小。

-XX:+UseFastAccessorMethods:使用get,set方法转成本地代码,原始类型的快速优化。

-XX:+UseCMSInitiatingOccupancyOnly:只有在oldgeneration在使用了初始化的比例后 concurrent collector 启动收集。

-Duser.timezone=Asia/Shanghai:设置用户所在时区。

-Djava.awt.headless=true:这个参数一般我们都是放在最后使用。有时我们会在我们的J2EE工程中使用一些图表工具,如:jfreechart,用于在Web 网页输出GIF/JPG等流,在Windows环境下,一般我们的app server在输出图形时不会碰到什么问题,但是在Linux/Unix 环境下经常会碰到一个 exception 导致你在 Windows开发环境下图片正常显示,可是在Linux/Unix下却显示不出来,因此加上这个参数以免避这样的情况出现。

-Xmn:新生代的内存空间大小,注意:此处的大小是(eden+ 2 survivor space)。与 jmap -heap 中显示的 New gen 是不同的。整个堆大小 = 新生代大小 + 老生代大小 + 永久代大小。在保证堆大小不变的情况下,增大新生代后,将会减小老生代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的 3/8。

-XX:CMSInitiatingOccupancyFraction:当堆满之后,并行收集器便开始进行垃圾收集。例如,当没有足够的空间来容纳新分配或提升的对象。对于CMS收集器,长时间等待是不可取的,因为在并发垃圾收集期间应用持续在运行(并且分配对象)。因此,为了在应用程序使用完内存之前完成垃圾收集周期,CMS收集器要比并行收集器更先启动。因为不同的应用会有不同对象分配模式,JVM会收集实际的对象分配(和释放)的运行时数据,并且分析这些数据,来决定什么时候启动一次CMS垃圾收集周期。这个参数设置有很大技巧,基本上满足(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100 >= Xmn就不会出现 promotion failed。例如在应用中Xmx是6000,Xmn是512,那么 Xmx-Xmn是5488M,也就是老年代有 5488M,CMSInitiatingOccupancyFraction=90 说明老年代到 90% 满的时候开始执行对老年代的并发垃圾回收(CMS),这时还 剩10%的空间是 5488*10% = 548M,所以即使 Xmn(也就是新生代共512M)里所有对象都搬到老年代里,548M 的空间也足够了,所以只要满足上面的公式,就不会出现垃圾回收时的promotion failed,因此这个参数的设置必须与Xmn关联在一起。

-XX:+CMSIncrementalMode:该标志将开启 CMS 收集器的增量模式。增量模式经常暂停 CMS 过程,以便对应用程序线程作出完全的让步。因此,收集器将花更长的时间完成整个收集周期。因此,只有通过测试后发现正常 CMS 周期对应用程序线程干扰太大时,才应该使用增量模式。由于现代服务器有足够的处理器来适应并发的垃圾收集,所以这种情况发生得很少,用于但 CPU情况。

-XX:NewRatio:年轻代(包括 Eden 和两个 Survivor 区)与年老代的比值(除去持久代),-XX:NewRatio=4 表示年轻代与年老代所占比值为 1:4,年轻代占整个堆栈的 1/5,Xms=Xmx 并且设置了Xmn的情况下,该参数不需要进行设置。

-XX:SurvivorRatio:Eden 区与 Survivor 区的大小比值,设置为 8,表示 2 个 Survivor 区(JVM 堆内存年轻代中默认有 2 个大小相等的 Survivor 区)与 1 个 Eden 区的比值为 2:8,即 1 个 Survivor 区占整个年轻代大小的 1/10。

-XX:+UseSerialGC:设置串行收集器。

-XX:+UseParallelGC:设置为并行收集器。此配置仅对年轻代有效。即年轻代使用并行收集,而年老代仍使用串行收集。

-XX:+UseParallelOldGC:配置年老代垃圾收集方式为并行收集,JDK6.0 开始支持对年老代并行收集。

-XX:ConcGCThreads:早期 JVM 版本也叫-XX:ParallelCMSThreads,定义并发 CMS 过程运行时的线程数。比如 value=4 意味着 CMS 周期的所有阶段都以 4 个线程来执行。尽管更多的线程会加快并发 CMS 过程,但其也会带来额外的同步开销。因此,对于特定的应用程序,应该通过测试来判断增加 CMS 线程数是否真的能够带来性能的提升。如果还标志未设置,JVM 会根据并行收集器中的 -XX:ParallelGCThreads 参数的值来计算出默认的并行 CMS 线程数。

-XX:ParallelGCThreads:配置并行收集器的线程数,即:同时有多少个线程一起进行垃圾回收,此值建议配置与CPU数目相等。

-XX:OldSize:设置JVM启动分配的老年代内存大小,类似于新生代内存的初始大小 -XX:NewSize。

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

测试前,先还原Tomcat到默认的配置文件,重启后压测一组优化前压测截图,如图11.11所示。

tomcat和iis的区别(tomcat和iis是干什么的)

图11.11

上述关于jvm优化参数太多,很多参数需要对GC回收有很深刻的认识。如果优化的不合适,往往会起到事倍功半的效果。下面是常见的优化参数,修改/usr/local/tomcat/bin/catalina.sh,增加红色字体。

# OS specific support. $var _must_ be set to either true or false.

JAVA_OPTS=”-server -Xms4096m -Xmx4096m -XX:PermSize=2048m -XX:MaxPermSize=2048m”

cygwin=false

darwin=false

重启Tomcat服务再次进行一轮压测,如图11.12所示。

tomcat和iis的区别(tomcat和iis是干什么的)

图11.12

从结果看优化后的平均值和90%响应时间比优化前的快。

结论:在每次优化完后压测数据都可能会存在差异,甚至环境一样压测结果都会不一样,一般都是取多组数据平均值。本案例中的简单的优化配置也不一定适合你的环境,但是至少优化的方向是正确的。如果想对jmeter进行深入学习,请查阅相关文档。

11.2.5 常见错误说明

1.java.lang.OutOfMemoryError: Java heap space——JVM Heap(堆)溢出

JVM 在启动的时候会自动设置JVM Heap的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)不可超过物理内存。可以利用JVM提供的 -Xmn -Xms -Xmx等选项可进行设置。Heap的大小是Young Generation和Tenured Generaion之和。在 JVM中如果98%的时间是用于GC,且可用的Heap size不足2%的时候将抛出此异常信息。

解决方法:手动设置 JVM Heap(堆)的大小。

2. java.lang.OutOfMemoryError: PermGen space——PermGen space溢出

PermGen space的全称是 Permanent Generation space,是指内存的永久保存区域。为什么会内存溢出,这是由于这块内存主要是被JVM存放Class和Meta信息的,Class在被Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同,sun 的GC不会在主程序运行期对PermGen space进行清理。所以,如果你的APP会载入很多 CLASS的话,就很可能出现PermGen space溢出。

解决方法:手动设置 MaxPermSize 大小。

3. java.lang.StackOverflowError——栈溢出

JVM依然是采用栈式的虚拟机,这个和C与Pascal都是一样的。函数的调用过程都体现在堆栈和退栈上了。调用构造函数的”层”太多了,以致于把栈区溢出了。通常来讲,一般栈区远远小于堆区的,因为函数调用过程往往不会多于上千层,而即便每个函数调用需要 1K 的空间(这个大约相当于在一个C函数内声明了256个int类型的变量),那么栈区也不过是需要1MB 的空间。通常栈的大小是1-2MB的。通常递归也不要递归的层次过多,很容易溢出。

解决方法:修改程序。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至QQ邮箱:3628405936@qq.com 举报,本站将立刻删除。
(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注