Tomcat企业应用实战

 

:安装Tomcat

1.软件下载

JDK地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

Tomcat地址: http://tomcat.apache.org/

 

2.安装JAVA

[  ! -d /app/tools ]  && mkdir  /app/tools  -p

[root@compute1tools]# tar xf jdk-8u40-linux-x64.tar.gz  -C  /app/

[root@compute1tools]# ln -sv  /app/jdk1.8.0_40/  /app/jdk

app/jdk->app/jdk1.8.0_40/

[root@compute1tools]#

 

[root@compute1app]# sed -i '$a export JAVA_HOME=/app/jdk\nexport PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin\nexport CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar' /etc/profile

 

[root@compute1app]# source  /etc/profile

[root@compute1app]# java  -version

java version"1.8.0_40"

Java(TM) SERuntime Environment (build 1.8.0_40-b26)

Java HotSpot(TM)64-Bit Server VM (build 25.40-b25, mixed mode)

 

3.安装Tomcat多实例

[root@compute1tools]# tar xf apache-tomcat-7.0.55.tar.gz  -C  /app/

[root@compute1app]# cp   -a  apache-tomcat-7.0.55/  tomcat7_1

[root@compute1app]# cp   -a  apache-tomcat-7.0.55/  tomcat7_2

 

.Tomcat管理界面

管理页面,可以查看tomcat自身的参数和部署在tomcat下的应用.默认该状态处于禁用状态.要想使用必须更改tomcat-user.xml文件进行开启.

[root@compute1 app]# sed  -i '36i <role  rolename="manager-gui"/>\n<role  rolename="admin-gui"/>\n<user username="tomcat" password="Aa123456Aa"  roles="manager-gui,admin-gui"/>'   tomcat7_1/conf/tomcat-users.xml

 

[root@compute1 app]# tail -n 4  tomcat7_1/conf/tomcat-users.xml

<role rolename="manager-gui"/>

<role rolename="admin-gui"/>

<user username="tomcat"  password="Aa123456"  roles="manager-gui,admin-gui"/>

</tomcat-users>

5.启动Tomcat

/app/tomcat7_1/bin/startup.sh

6.登录http://IP:8080


wKiom1bnc36Dli-zAAEzIo0XIWQ826.png

wKiom1bnc3-wB1YaAADehtIi4MU352.png

wKioL1bndAvh1RpNAADJVRP3DtM450.png

wKioL1bndAzR3k-LAAB7UDPGbrY100.png


.Tomcat主配置文件结构和参数解释

<server>
 <service>
 <Connector port="8080" address="0.0.0.0"protocol="HTTP/1.1" minProcessors="300"maxProcessors="2000" enableLookups="false"redirectPort="8443" acceptCount="3000"connectionTimeout="2000"/>
 <engine>
 <Host name="localhost"appBase="webapps" unpackWARs="true"autoDeloy="true">
 <Context path=""docBase="/app/tomcat7_1/webapps/virtual-platform" reloadable="true"crossContext="true"/>
 </Host>
 </engine>
 </service>
</server>

 

port   指定服务器端HTTP端口号

address:指定连接器监听的地址,默认为所有地址(即0.0.0.0)

protocol连接器使用的协议,支持HTTP和AJP。AJP是apache和tomcat的连接协议

minProcessors服务器启动时创建的处理请求的线程数

maxProcessors最大可以创建的处理请求的线程数

enableLookups是否查询客户端主机名.线上不开启,性能消耗严重

redirectPort在处理http请求时,遇到一个SSL请求,将要转发的端口

acceptCount排队数,超过此数值,不处理

connectionTimeout指定超时的时间数

 

 

name:  主机名

appBase: 网站根目录

unpackWARS:是否自动解压war包.若为false,则tomcat就在war内加载项目

autoDeloy:tomcat启动时自动部署项目

docBase: 应用程序的路径或者是WAR包项目的路径.

path:表示此web应用程序的url的前缀,这样请求的url为http://localhost:8080/path/****

reloadable:该参数为true表示.当WEB-INF/lib或者WEB-INF/classes目录中的文件发生变化的时候,会自动加载新的项目.不需要重新启动Tomcat.

 

.Tomcat容器优化

URIEncoding=”UTF-8”

Tomcat可以解析中文名的文件的url
maxSpareThreads

最大空闲线

minSpareThreads

最小空闲线

maxThreads

Tomcat使用线程来处理每个请求.这个值表示Tomcat建的最大的线程数,即最大并数。

enableLoopups="false" 

取消DNS查询

acceptCount

当达到maxThreads,求放到队列中去.队列满后,直接refuse connections.

compression="on"

打开压缩功能

compressionMinSize="2048"

启用压缩出内容大小,里面默认为2KB

compressableMimeType="text/html,text/xml" 

压缩类


 

:jvm优化

例子:

export JAVA_OPTS="-server-Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31-XX:+UseConcMarkSweepGC  -XX:+CMSParallelRemarkEnabled-XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true"

 

参考: http://blog.csdn.net/lifetragedy/article/details/7708724

-server

生产环境下必须打开,多CPU服务器,效果极好

-Xms与-Xmx

参考: http://blog.oldboyedu.com/java-tomcat/

老男孩老师建议:上面两个值是分配JVM的最小和最大内存,取决于硬件物理内存的大小,建议均设为物理内存的一半。

JVM内存置了,把XmsXmx两个值设成一是最的做法,不要初始化配小点,最大配大点,就完美无瑕了.那就大了.因内存全部达到Xmx会回落.回落cpu行高速运转进行垃圾回收.造成负载增加.Xms和Xmx相同,就无需行内存回落.无法造成负载高的情况.配置Xmx时需要按照下面执行以下.分配太大,可能无法正常使用.

 

wKioL1bndNuTN_b5AAByowiOBY4799.png

 

 

–Xmn

设置年轻代大小为512m。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。一般Xmx34分之一

-Xss

每个线程的堆栈大小.这个就要依据你的程序,看一个线需要占用多少内存,可能会有多少线程同运行等。一般不易置超1M,要不然容易出out ofmemory而最佳值应该128K,认值好像是512k.

-XX:+AggressiveOpts

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

-XX:+UseBiasedLocking

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

 -XX:PermSize=128M-XX:MaxPermSize=256M

JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;Tomcat8不在支持.

在数据量的很大的文件导出时,一定要把这两个值设置上,否则会出现内存溢出的错误。

由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

那么,如果是物理内存4GB,那么64分之一就是64MB,这就是PermSize默认值,也就是永生代内存初始大小;

四分之一是1024MB,这就是MaxPermSize默认大小。

 -XX:+DisableExplicitGC

在程序代码中不允许有显示的调用”System.gc()”。看到过有两个极品工程中每次在DAO操作结束时手动调用System.gc()一下,觉得这样做好像能够解决它们的out ofmemory问题一样,付出的代价就是系统响应时间严重降低,就和我在关于Xms,Xmx里的解释的原理一样,这样去调用GC导致系统的JVM大起大落,性能不到什么地方去哟!

 -XX:+UseParNewGC

对年轻代采用多线程并行回收,这样收得快。Tomcat8不在支持.

 -XX:+UseConcMarkSweepGC

即CMS gc,这一特性只有jdk1.5即后续版本才具有的功能,它使用的是gc估算触发和heap占用触发。

我们知道频频繁的GC会造面JVM的大起大落从而影响到系统的效率,因此使用了CMS GC后可以在GC次数增多的情况下,每次GC的响应时间却很短,比如说使用了CMS GC后经过jprofiler的观察,GC被触发次数非常多,而每次GC耗时仅为几毫秒。

 -XX:MaxTenuringThreshold

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

这个值的设置是根据本地的jprofiler监控后得到的一个理想的值,不能一概而论原搬照抄。

 -XX:+CMSParallelRemarkEnabled

在使用UseParNewGC 的情况下, 尽量减少 mark 的时间

 -XX:+UseCMSCompactAtFullCollection

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

-XX:LargePageSizeInBytes

指定 Java heap的分页页面大小

 -XX:+UseFastAccessorMethods

get,set方法转成本地代码

-XX:+UseCMSInitiatingOccupancyOnly

指示只有在 oldgeneration 在使用了初始化的比例后concurrentcollector 启动收集

 -XX:CMSInitiatingOccupancyFraction=70

CMSInitiatingOccupancyFraction,这个参数设置有很大技巧,基本上满足(Xmx-Xmn)*(100-CMSInitiatingOccupancyFraction)/100>=Xmn就不会出现promotion failed。在我的应用中Xmx是6000,Xmn是512,那么Xmx-Xmn是5488兆,也就是年老代有5488 兆,CMSInitiatingOccupancyFraction=90说明年老代到90%满的时候开始执行对年老代的并发垃圾回收(CMS),这时还 剩10%的空间是5488*10%=548兆,所以即使Xmn(也就是年轻代共512兆)里所有对象都搬到年老代里,548兆的空间也足够了,所以只要满 足上面的公式,就不会出现垃圾回收时的promotionfailed;

因此这个参数的设置必须与Xmn关联在一起。

-Dfile.encoding=utf-8

JAVA日志字符集


-Duser.timezone=Asia/Shanghai

JAVA项目时区


-Djava.awt.headless=true

这个参数一般我们都是放在最后使用的,这全参数的作用是这样的,有时我们会在我们的J2EE工程中使用一些表工具如:jfreechart,用于在web页输GIF/JPG等流,在winodws环境下,一般我们的app server不会碰到什么问题,但是在linux/unix环境下经常会碰到一个exception导致你在winodws发环境下示的好好可是在linux/unix下却示不出来,比如验证码.因此加上个参数以免避这样的情况出现.