前言:

Tomcat服务器是一个免费的开源web应用服务器,属于轻量级应用服务器,在中小型系统和并发用户不是很多的场合中被普遍使用,是开发和测试JSP程序的首选。一般来说,Tomcat虽然和apache或者Nginx这些web服务器一样,具有处理HTML页面的功能,然而由于其处理静态页面的能力远不如apache或者Nginx,所以Tomcat一般是作为一个servlet和JSP容器,单独运行在后端。

关于Tomcat服务的各个目录的说明及配置文件的解释,可以参考博文:Tomcat服务器配置文件详解,或者访问其Tomcat官网,以阅读官方文档。


博文大纲: 一、部署Tomcat 二、定义Tomcat多实例 三、配置Tomcat自定义目录 四、开启Tomcat目录遍历 五、使用Tomcat实时监控JVM虚拟机资源使用情况 六、开启JMX远程调试功能 七、开启mangent管理页面 八、开启host-mangent管理页面 九、Tomcat的运行日志切割 十、定义Tomcat 404错误返回的页面 十一、Tomcat服务的内存优化 十二、Tomcat线程池的优化 十三、修改Tomcat服务的请求方式

一、部署Tomcat

环境准备:

  • centos 7一台,IP为:192.168.20.5
  • 下载我提供的所需源码包,并上传至centos 7服务器。

注:上面的下载链接中有一个名为“tomcat”的文件,那是tomcat服务的控制脚本,可以将其上传到Tomcat服务器的/etc/init.d/目录下,然后使用chmod命令赋予其执行权限,即可实现使用此脚本对Tomcat服务进行启动、停止、重启等操作。

1、开始部署

[root@tomcat ~]# rpm -qa | grep jdk       #查询系统默认的JAVA包
java-1.8.0-openjdk-1.8.0.102-4.b14.el7.x86_64
java-1.8.0-openjdk-headless-1.8.0.102-4.b14.el7.x86_64
java-1.7.0-openjdk-1.7.0.111-2.6.7.8.el7.x86_64
copy-jdk-configs-1.2-1.el7.noarch
java-1.7.0-openjdk-headless-1.7.0.111-2.6.7.8.el7.x86_64
[root@tomcat ~]# rpm -e java-1.8.0-openjdk-headless --nodeps        #卸载Java1.8
[root@tomcat ~]# rpm -e java-1.7.0-openjdk-headless --nodeps        #卸载Java1.7
[root@tomcat ~]# cd /usr/src
[root@tomcat src]# rz      #上传我提供的两个源码包
[root@tomcat src]# ls         #源码包如下
apache-tomcat-8.5.35.tar.gz  jdk-8u211-linux-x64.tar.gz
[root@tomcat ~]# tar zxf jdk-8u211-linux-x64.tar.gz -C /usr/local/   #解压JDK到指定路径
[root@tomcat src]# tar zxf apache-tomcat-8.5.35.tar.gz   #解压Tomcat源码包
[root@tomcat src]# mv apache-tomcat-8.5.35 /usr/local/tomcat   #将解压后的目录移动到指定目录并命名为tomcat
[root@tomcat ~]# vim /etc/profile         #编辑环境变量,在配置文件末尾添加以下内容
export JAVA_HOME=/usr/local/jdk1.8.0_211
export JRE_HOME=/usr/local/jdk1.8.0_211/jre
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
[root@tomcat ~]# . /etc/profile       #重新加载环境变量
[root@tomcat ~]# java -version       #查看java版本
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
[root@tomcat ~]# /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/local/jdk1.8.0_211/jre
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@tomcat src]# netstat -anput | grep 8080      #确定8080端口在监听

至此,Tomcat服务就运行正常了,可以使用客户端访问Tomcat服务器IP+8080端口,可以看到以下页面:

二、定义Tomcat多实例

所谓多实例,就是在一台服务器上运行多个Tomcat服务,所以,需要注意,在定义Tomcat的多实例时,千万不要出现端口冲突的情况。

[root@tomcat src]# cd /usr/local/           #切换至Tomcat服务的安装目录
[root@tomcat local]# cp -r tomcat tomcat2    #将第一个Tomcat目录复制一份并重命名为tomcat2。
[root@tomcat local]# vim tomcat2/conf/server.xml        #修改主配置文件中的所有端口号,防止端口冲突
#配置文件的所有端口号,除了带注释的外,都需要修改,
#只要配置项中带有“port”的,并且后面是数字的,都是端口号
#由于其分散在各个行,所以这里就不写了,自行修改即可,我这里都将其+1
[root@tomcat local]# cd
[root@tomcat ~]# /usr/local/tomcat2/bin/startup.sh    #使用Tomcat2启动脚本运行Tomcat2
[root@tomcat ~]# netstat -natp | grep 8081    #确定修改后的端口在监听

至此,第二个Tomcat实例就运行正常了,可以使用客户端访问Tomcat服务器IP+8081端口,可以看到以下页面(由于是完全复制之前的Tomcat目录,所以看到的页面一样):

三、配置Tomcat自定义目录

[root@tomcat ~]# mkdir -p /data/project         #创建目录
[root@tomcat ~]# cat /data/project/index1.jsp     #第一个网页文件
aaaaaaaaaaaaaaaaaaaaaaa
[root@tomcat ~]# cat /data/project/index2.jsp   #第二个网页文件
bbbbbbbbbbbbbbbbbbbbbbbbbbb
[root@tomcat ~]# vim /usr/local/tomcat/conf/server.xml    #编辑Tomcat主配置文件
      <Host name="localhost"  appBase="webapps"    #定位到148行左右
            unpackWARs="true" autoDeploy="true">    
						..........................#添加以下内容
        <Context path = "/shop" docBase="/data/project" debug="0" reloadable="false" crossContext="true">
        </Context>
#添加上述 <Context....> </Context>的配置后即可保存退出
#上述的 <Context....> </Context>标签的另一种写法就是<Context......./>
#在上述添加的配置解释如下:
#Path:指出客户端访问的路径;
#docBase:指定网页的存放路径;
#Debug:指定debug的等级为0,输出信息最少,9提供最多的信息;
#reloadable:为true时表示当web.xml文件有改动的时候自动加载,不必重启服务;
#CorssContext:为true时,表示不同的context共享一个session(会话池)。
#重启访问http://192.168.20.5:8080/shop/index1/2.jsp进行验证即可
[root@tomcat ~]# /usr/local/tomcat/bin/shutdown.sh        #停止Tomcat  
[root@tomcat ~]# /usr/local/tomcat/bin/startup.sh     #启动Tomcat

访问192.168.20.5:8080/shop/index1.jsp 进行验证:

访问192.168.20.5:8080/shop/index2.jsp 进行验证:

四、开启Tomcat目录遍历

在apache或Nginx中,它们的目录遍历是默认开启的,而Tomcat服务,它的目录遍历默认是关闭的,有些情况下,我们需要开启它的目录遍历功能。

1、直接访问192.168.20.5:8080/shop/进行测试,会报错404:

2、那么,接下来开启它的目录遍历功能:

[root@tomcat ~]# vim /usr/local/tomcat/conf/web.xml    #编辑这个文件
<init-param>               #定位到该标签,110行左右
            <param-name>listings</param-name>
            <param-value>true</param-value>         #将原本的false修改为true
#修改后,保存退出即可
#重启Tomcat服务
[root@tomcat ~]# /usr/local/tomcat/bin/shutdown.sh          
[root@tomcat ~]# /usr/local/tomcat/bin/startup.sh

3、重启后,刷新刚才的访问页面,会发现网页将其shop/指定的目录下的所有文件都显示出来了,如下:

五、使用Tomcat实时监控JVM虚拟机资源使用情况

[root@tomcat ~]# vim /usr/local/tomcat/conf/server.xml
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Context path = "/shop" docBase="/data/project" debug="0" reloadable="false" crossContext="true">
        </Context>         #在下面添加一行
        <Context path = "monit" docBase="/data/monit" debug="0" reloadable="flase" crossContext="true"/>
#添加后,保存退出即可
[root@tomcat ~]# mkdir /data/monit
[root@tomcat ~]# vim /data/monit/index.jsp      #编写监控脚本,写入以下内容
<%
Runtime rtm = Runtime.getRuntime();
long mm = rtm.maxMemory()/1024/1024;
long tm = rtm.totalMemory()/1024/1024;
long fm = rtm.freeMemory()/1024/1024;

out.println("JVM memory detail info :<br>");
out.println("Max memory:"+mm+"MB"+"<br>");
out.println("Total memory: "+tm+"MB"+"<br>");
out.println("Free memory: "+fm+"MB"+"<br>");
out.println("Available memmory can be used is :"+(mm+fm-tm)+"MB"+"<br>");
%>
#保存后,保存退出即可
#重启
[root@tomcat ~]# /usr/local/tomcat/bin/shutdown.sh          
[root@tomcat ~]# /usr/local/tomcat/bin/startup.sh

访问192.168.20.5:8080/monit/会看到以下页面:

六、开启JMX远程调试功能

[root@tomcat ~]# vim /usr/local/tomcat/bin/catalina.sh          #编辑其文件,跳转文件的306行
export JDK_JAVA_OPTIONS        #在该行下面添加以下内容,定义其监听端口为“8888”
CATALINA_OPTS=" $CATALINA_OPTS  -Dcom.sun.management.jmxremote  -Dcom.sun.management.jmxremote.port=8888 -Dcom.sun.management.jmxremote.ssl=false  -Dcom.sun.management.jmxremote.authenticate=true"
#添加完成后,保存退出即可
[root@tomcat ~]# cd /usr/local/jdk1.8.0_211/jre/lib/management/
[root@tomcat management]# cp jmxremote.password.template jmxremote.password
[root@tomcat management]# vim jmxremote.password       #在文件末尾写入需要创建的用户,如下:
ljz     123.com
#由于其是一个只读文件,所以在写入后,需要使用命令“wq!”以便强制保存
[root@tomcat management]# vim jmxremote.access      #编辑此文件,给用户定义权限
#跳转至文件末尾,添加以下配置项,也可以直接修改末尾的模板
ljz   readwrite \             #此行开头指定的是用户名
              create javax.management.monitor.*,javax.management.timer.* \
              unregister
#写入以上内容后,保存退出即可
[root@tomcat management]# chmod 600 jmxremote.access jmxremote.password     #必须修改其权限为600,否则会失败
#重启Tomcat服务
[root@tomcat ~]# /usr/local/tomcat/bin/shutdown.sh          
[root@tomcat ~]# /usr/local/tomcat/bin/startup.sh

验证其远程调试功能,由于其需要图形化的支持,所以需要进入其图形化桌面环境,下面的操作不可以在xshell上进行了:

[root@tomcat ~]# jconsole          #执行此命令
#若上述命令无法执行,则需要执行“. /etc/profile”命令,以便重新加载环境变量

执行jconsole命令后,会弹出以下界面:

然后点击如下:

就可以看到以下界面,其中显示的是JVM虚拟机的资源使用情况:

七、开启mangent管理页面

1、在访问Tomcat的默认界面时,有一个“Manager App”的框,如下:

2、点击进入后,会看到以下403报错页面(翻译过后如下),我们需要复制它提示的代码:

此错误页面,已经将原因及该如何配置写的明明白白的。

3、现在配置开启它的manager管理页面:

[root@tomcat ~]# vim /usr/local/tomcat/conf/tomcat-users.xml      #编辑这个文件,跳转至文件末尾
<role rolename="manager-gui"/>
<user username="lisi" password="123.com" roles="manager-gui"/>
</tomcat-users>       #在这个闭合的标签上面添加两行,以便添加用户
#添加的配置项中,“username”为用户名,“password”为用户密码。
[root@tomcat ~]# vim /usr/local/tomcat/webapps/manager/META-INF/context.xml    #编辑此文件,添加允许访问的IP
         allow="192.168.20.254|192.168.20.5|127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />   
				 #在上面“allow=”后添加允许访问的IP,以管道符“ | ”为分割
  <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>
#重启服务验证
[root@tomcat ~]# /usr/local/tomcat/bin/shutdown.sh          
[root@tomcat ~]# /usr/local/tomcat/bin/startup.sh

4、使用客户端访问它的默认首页,然后点击“Manager App”,会看到以下界面,输入用户名及密码:

5、登录后,即可看到我们的Tomcat根目录下的自定义目录:

6、下拉页面,可以通过war包添加自定义的目录:

1)准备war包:

[root@tomcat ~]# vim index.jsp        #编写jsp网页文件
test
test
[root@tomcat ~]# jar -cvf test.war index.jsp     #做成war包,名为“test.war”

2)在web图形界面,添加war包:

3)部署后,即可看到以下内容:

4)客户端可以访问TomcatIP+8080端口+/aaa进行访问测试,其内容就是我们做的war包中的内容,如下:

八、开启host-mangent管理页面

1、访问以下页面,然后复制其提示的代码:

[root@tomcat ~]# vim /usr/local/tomcat/conf/tomcat-users.xml  #编辑其配置文件
<role rolename="admin-gui"/>
<user username="lv" password="123.com" roles="admin-gui"/>
</tomcat-users>       #在末尾这行上面添加复制的代码,并修改用户名及密码
[root@tomcat ~]# vim /usr/local/tomcat/webapps/host-manager/META-INF/context.xml       #修改这个文件
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="192.168.20.254|127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />  #在这行添加允许访问的IP来源
#修改后保存退出即可
#重启验证
[root@tomcat ~]# /usr/local/tomcat/bin/shutdown.sh          
[root@tomcat ~]# /usr/local/tomcat/bin/startup.sh

2、客户端验证:

重新点击,即可提示输入密码:

至此,即可通过此页面管理tomcat的域名信息了,不过这个功能在生产环境中不建议使用。

九、Tomcat的运行日志切割

cronolog是一个第三方的日志切割工具,比较方便快捷,是日志切割的一大利器。这里就使用这个第三方工具。

1、上传博文开头下载链接中的cronolog-1.6.2.tar.gz源码包到Tomcat服务器。

[root@tomcat ~]# tar zxf cronolog-1.6.2.tar.gz -C /usr/src     #解包
[root@tomcat ~]# cd /usr/src/cronolog-1.6.2/
[root@tomcat cronolog-1.6.2]# ./configure && make && make install    #编译安装
[root@tomcat cronolog-1.6.2]# which cronolog    #确定可以查到该命令
/usr/local/sbin/cronolog
[root@tomcat cronolog-1.6.2]# cd /usr/local/tomcat/       #切换至Tomcat主目录
[root@tomcat tomcat]# vim bin/catalina.sh    #编辑此文件
搜索touch,并且注释掉,如:#touch "$CATALINA_OUT"
然后跳转到470行左右,修改如下:
      org.apache.catalina.startup.Bootstrap "$@" start  2>&1 | /usr/local/sbin/cronolog /usr/local/tomcat/logs/test.%Y-%m-%d.out >> /dev/null &
并且注释掉473行左右的这一行,如:     #>> "$CATALINA_OUT" 2>&1 "&"
#重启验证
[root@tomcat ~]# /usr/local/tomcat/bin/shutdown.sh          
[root@tomcat ~]# /usr/local/tomcat/bin/startup.sh
#验证:
[root@tomcat tomcat]# ls logs/    #确认该目录下有“test.2019-10-28.out”即可
catalina.2019-10-28.log      localhost_access_log.2019-10-28.txt
catalina.out                 manager.2019-10-28.log
host-manager.2019-10-28.log  test.2019-10-28.out
localhost.2019-10-28.log

十、定义Tomcat 404错误返回的页面

默认情况,客户端访问Tomcat服务器上一个不存在的目录时,会提示404错误,而且会将我们Tomcat的版本信息等显示出来,这是我们比较忌讳的,默认的404返回的错误页面如下:

解决办法就是,将404状态码进行重定向,以便我们自定义返回的页面信息,如下:

[root@tomcat tomcat]# cat /usr/local/tomcat/webapps/ROOT/error.jsp
#自定义的错误页面如下:
Access Error...           
[root@tomcat ~]# vim /usr/local/tomcat/conf/web.xml    #编辑该文件
  version="3.1">            #在这行下面(第22行附近)添加以下内容
<error-page>
<error-code>404</error-code>
<location>/error.jsp</location>
</error-page>
#重启验证
[root@tomcat ~]# /usr/local/tomcat/bin/shutdown.sh          
[root@tomcat ~]# /usr/local/tomcat/bin/startup.sh

此时,再次访问一个不存在的URL,就会看到以下页面,如下:

十一、Tomcat服务的内存优化

[root@tomcat ~]# vim /usr/local/tomcat/bin/catalina.sh    #编辑此文件

#!/bin/sh          #在第一行下面添加以下内容
JAVA_OPTS="-Dfile.encoding=UTF-8
-server
-Xms1023M
-Xmx1024M
-XX:NewSize=512M
-XX:MaxNewSize=1020M
-XX:NewRatio=2
-XX:ParallelGCThreads=15
-XX:+DisableExplicitGC"
#添加完成后,保存退出后,重启Tomcat后,即可生效,
#可以通过之前的实时监控JVM虚拟机资源使用进行查看验证
#若是在Tomcat 8.0之前的版本,还可以在上面添加以下两个配置项,8.0以后的版本就被移除了:
#-XX:PermSize=256M
#-XX:MaxPermSize=356M
               

添加的各个配置项解释如下:

  • -Xms:表示 JVM初始内存大小,也可以说是Java 初始化堆的大小,-Xms 与-Xmx 设成一样的值,避免 JVM 反复重新申请内存,导致性能大起大落,默认值为物理内存的 1/64
  • -Xmx:表示最大 Java 堆大小,当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃,因此一般建议堆的最大值设置为可用内存的最大值的80%。
  • -Xmn:设置JVM最小内存(128-256就够了,一般不设置)
  • -XX:NewSize:设置新生代内存大小。 新生代,对象新创建的时候分配的内存空间,老生代在垃圾回收器回收过后该对象依然没有被回收,该对象就会移动到老生代
  • -XX:PermSize:设置持久代内存大小,用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应 用可能动态生成或者调用一些class,持久带也称为方法区,方法区存储每一个java类的结构信息:比如运行时常量池,字段和方法数据,构造函数和普通方法的字节码内容以及类、实例、接口初始化时需要使用到的特殊方法等数据,JDK8中已经把持久代(PermGen Space) 干掉了,取而代之的元空间(Metaspace)。Metaspace占用的是本地内存,不再占用虚拟机内存。
  • -XX:MaxPermSize:设置最大值持久代内存大小,永久代不属于堆内存,堆内存只包含新生代和老年代
  • -XX:NewRatio:改变新旧空间的比例,意思是新空间的尺寸是旧空间的1/8(默认为8)
  • -XX:ParallelGCThreads 可用来增加并行度,需要多cpu
  • -XX:+DisableExplicitGC:关闭System.gc(),简单理解就是关闭java中的内存回收机制

十二、Tomcat线程池的优化

[root@tomcat ~]# vim /usr/local/tomcat/conf/server.xml   #编辑主配置文件
 <Service name="Catalina">                #在53行下添加以下内容
     <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="500" minSpareThread="4"/>
<Connector port="8080" protocol="HTTP/1.1"          #在69行下面添加以下配置,以便进行调用
               executor="tomcatThreadPool"

上述Excutor重要参数说明:

  • name:共享线程池的名字,这是connector为了共享线程池要引用的名字,该名称必须唯一
  • namePrefix:在JVM上,每运行线程都可以有一个name字符串,这一属性为线程池中每个线程的name字符串设置了一个前缀,Tomcat将把线程号追加到这一前缀后面,默认值为tomcat-exec-
  • maxThreads:该线程池可以容纳的最大线程数,默认200
  • minSpareThreads:Tomcat应该始终打开的最小不活跃线程数,默认25 Connector参数说明
  • executor:表示使用参数值对应的线程池。

十三、修改Tomcat服务的请求方式

Tomcat支持的三种请求方式:BIO、NIO、APR。

  • BIO:阻塞式I/O操作,Tomcat7以下版本默认情况下是以bio模式运行的,每个请求都要创建一个线程来处理,线程开销比较大,不适用高并发的场景,性能也最低;
  • NIO:基于缓冲区,能提供非阻塞I/O操作,和传统的BIO相比,具备更好的并发性能
  • APR(Apache portable run-time libraries):简单理解,就是从操作系统级别解决异步IO问题,大幅度的提高服务器的处理和相应性能,也是Tomcat运行高并发的首选模式

APR提供的主要功能模块包括:内存分配及内存池、原子操作、文件I/O、锁、内存映射、哈希表、网络I/O、轮询、进程及线程操作等等,通过采用APR,Tomcat可以获得高度可扩展性以及优越的性能,并且可以更好的与本地服务器技术集成,从而可以使Tomcat作为一款通用的Web服务器使用,而不仅仅作为轻量级应用服务器。在这种情况下,Java将不再是一门侧重于后端的编程语言,也可以更多的用于成熟的Web服务器平台。

1、更改其请求方式为NIO(注意:Tomcat8以上版本,默认使用的就是NIO模式,不需要额外修改 )

[root@tomcat ~]# vim /usr/local/tomcat/conf/server.xml        #修改主配置文件
 <Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"           #修改其protocol
               executor="tomcatThreadPool"
               connectionTimeout="20000"
               redirectPort="8443" />
#修改完成后,保存退出,重启Tomcat服务即可

重启后,查看其“catalina.out”日志,有以下字样,则表示是在nio接收请求处理方式,如下(我这里在上面对catalina.out进行了日志切割,所以需要查看切割后的日志文件):

2、更改其请求方式为APR模式

启用这种模式稍微麻烦一些,需要安装一些依赖库,下面是基于centos 7.3环境的Tomcat/8.5.35进行配置。

1)安装apr动态库

[root@tomcat ~]# yum -y install apr-devel openssl-devel gcc make      #安装所需依赖
[root@tomcat ~]# cd /usr/local/tomcat/bin/
[root@tomcat bin]# tar zxf tomcat-native.tar.gz 
[root@tomcat bin]# cd tomcat-native-1.2.18-src/native/
[root@tomcat native]# ./configure && make && make install   #安装apr动态库
#编译安装完成后,apr动态库默认安装在/usr/local/apr/lib目录下。

2)配置APR本地库到系统共享库搜索路径中

设置LD_LIBRARY_PATH和LD_RUN_PATH环境变量,指向/usr/local/apr/lib目录,可配置到/etc/profile文件中。如下:

[root@tomcat native]# vim /etc/profile              #编辑全局变量,在文件末尾写入以下两行
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/apr/lib
export LD_RUN_PATH=$LD_RUN_PATH:/usr/local/apr/lib
[root@tomcat native]# . /etc/profile        #重新加载环境变量
#重启验证
[root@tomcat ~]# /usr/local/tomcat/bin/shutdown.sh          
[root@tomcat ~]# /usr/local/tomcat/bin/startup.sh

重启后,查看其“catalina.out”日志,有以下字样,则表示是在apr接收请求处理方式,如下(我这里在上面对catalina.out进行了日志切割,所以需要查看切割后的日志文件):

———————— 本文至此结束,感谢阅读 ————————