Tomcat8理论、自定义目录、目录浏览、多实例、JVM内存监控、JMX远程调用、后台管理、优化

概述

Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个servelet容器,按照Sun microsystems提供的技术规范开发出来,Tomcat 8实现了对servlet 3.1和Javaserver page 2.3(JSP)的支持,并提供了作为web服务器的一些特有功能,如Tomcat管理和控制平台、安全域管理和Tomcat附加组件等

Servlet是Java提供的用于开发Web服务器应用程序的一个组件,运行在服务器端,由Servlet容器所管理,用于生成动态的内容。Servlet是平台独立的Java类,编写一个Servlet,实际上就是按照Servlet规范编写一个Java类。
JSP是servlet的扩展,可以认为JSP = HTML + Java代码 + JSP标签
Servlet获取请求数据和处理数据非常方便,但是向页面输出并显示数据(html标签)非常麻烦,毫无格式
jsp显示数据非常方便,像html格式一样,但是封装数据和处理数据比较麻烦

安装

  • RPM包
  • 二进制安装包

配置JDK环境

jdk介绍

  • jdk(java development kit)是java语言的软件开发工具包
  • 其中基本组件包括:
    javac – 编译器,将源程序转成字节码
    jar – 打包工具,将相关的类文件打包成一个文件
    javadoc – 文档生成器,从源码注释中提取文档
    jdb – debugger,查错工具
    java – 运行编译后的java程序(.class后缀的)
    appletviewer:小程序浏览器,一种执行HTML文件上的Java小程序的Java浏览器。
    Javah:产生可以调用Java过程的C过程,或建立能被Java程序调用的C过程的头文件。
    Javap:Java反汇编器,显示编译类文件中的可访问功能和数据,同时显示字节代码含义。
    Jconsole: Java进行系统调试和监控的工具
    xtcheck:一个检测jar包冲突的工具
    apt:注释处理工具
    jhat:java堆分析工具
    jstack:栈跟踪程序
    jstat:JVM检测统计工具
    jstatd:jstat守护进程
    jinfo:获取正在运行或崩溃的java程序配置信息
    jmap:获取java进程内存映射信息
    idlj:idl-to-java编译器,将IDL语言转化为java文件
    policytool:一个GUI的策略稳健和管理工具
    jrunscript:命令行脚本运行

配置jdk环境

下载:
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
(需要点介绍协议,下载jdk8)

[root@localhost ~]# tar -zxf jdk-8u201-linux-x64.tar.gz -C /usr/local/
[root@localhost ~]# ls /usr/local/
bin  etc  games  include  jdk1.8.0_201  lib  lib64  libexec  sbin  share  src
[root@localhost ~]# vim /etc/profile  末尾追加内容
export JAVA_HOME=/usr/local/jdk1.8.0_201
export JRE_HOME=/usr/local/jdk1.8.0_201/jre
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
[root@localhost ~]# source /etc/profile
[root@localhost ~]# java -version
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)
[root@localhost ~]# 

解压和运行

[root@localhost ~]# tar -zxf apache-tomcat-8.5.35.tar.gz -C /usr/local/

运行(默认监听8080端口)
[root@localhost ~]# /usr/local/apache-tomcat-8.5.35/bin/startup.sh 

停止服务
[root@localhost ~]# /usr/local/apache-tomcat-8.5.35/bin/shutdown.sh 

配置

目录结构

程序目录
在这里插入图片描述
bin ——Tomcat执行脚本目录
conf ——Tomcat配置文件
lib ——Tomcat运行需要的库文件(JARS)
logs ——Tomcat执行时的LOG文件
temp ——Tomcat临时文件存放目录
webapps ——Tomcat的主要Web发布目录(存放我们自己的JSP,SERVLET,类)
work ——Tomcat的工作目录,Tomcat将翻译JSP文件到的Java文件和class文件放在这里

web工程发布目录结构
在这里插入图片描述
webapps是Tomcat的主要Web发布目录,默认情况下把Web应用文件放于此目录
项目名: 项目名下面有WEB-INF ,META-INF,两个文件夹,和一些给浏览器访问的资源,如html文件;

WEB-INF:可以称为是安全目录,因为在这下面的文件,浏览器是访问不到的,

  1. web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。
  2. classes:包含所需要的 class 文件,包括 servlet class 和其他的一些class,他们不能包含在 .jar文件中。
  3. lib:存放web应用需要的各种JAR文件

META-INF:用来配置应用程序、扩展程序、类加载器和服务

默认webapps目录结构
在这里插入图片描述
docs:Tomcat帮助文档
examples:web应用实例
host-manager:主机管理
manager:应用管理
ROOT:默认站点根目录

配置文件

conf目录主要是用来存放tomcat的一些配置文件。

server.xml 主配置文件
web.xml 与其他适用于整个web应用程序设置的配置文件
context.xml 默认的context设置,应用于安装了Tomcat的所有主机的所有部署内容
tomcat-users.xml用来配置管理tomcat的用户与权限
catalina.xml Tomcat的安全防护策略文件

组件

  1. Server提供一个接口,由1至多个Service组成,让其它程序可以访问到这个Service集合,同时维护各个Service的生命周期,包括如何初始化,如何结束服务,如何找到别人请求的服务。

  2. Service又由1-n个Connector及单个Container组成,只是在Container和Connector外多包了一层,提供各种服务

  3. Connector组件是可选择替换的,负责接收浏览器发过来的TCP连接请求,创建Request/Response,分配线程,将创建的对象传递给Container来处理请求

  4. Container是容器的父接口,由四个容器组成,分别是Engine,Host,Context,Wrapper。其中Engine包含Host,Host包含Context,Content包含Wrapper,一个Servlet class对应一个Wrapper

  5. Engine容器是作为顶级Container组件来设计的,由Host组成,其作用相当于一个Container的门面。有了Engine,请求的处理过程变为:浏览器发出请求,Connector接受请求,将请求交由Container(这里是Engine)处理,Container(Engine来担当)查找请求对应的Host并将请求传递给它,Host拿到请求后查找相应的应用上下文环境,准备 servlet环境并调用service方法。

  6. Host容器是Engine的子容器,一个Host在Engine中代表一个虚拟主机,这个主机可以运行多个应用,他负责安装和展开这些应用,并且标识这个应用,以便能够区分他们。它的子容器通常是Context,他除了关联子容器外,还保存一个主机应有的信息。Host不是必需的,但是要运行 war程序,就必须要使用Host,因为在war中必有web.xml文件,这个文件解析就需要Host,如果有多个Host就需要定义一个top容器 Engine,而Engine没有父容器,一个Engine就代表一个完整的Servlet引擎

  7. Context代表Servlet的Context,它具备Servlet运行的基本环境,理论上只要有Context就能运行Servlet,简单的Tomcat可以没有Engine和Host。其最重要的功能就是管理Servlet实例,Servlet实例在Context中是以Wrapper 出现的。

  8. Wrapper代表一个Servlet,它负责管理Servlet,包括装载,初始化,执行以及资源回收。它是最底层的容器。

  9. valve 阀门,拦截请求并在将其转至对应的webapp前进行某种处理操作,可以用于任何容器中,比如记录日志、基于ip做访问控制

配置文件解读

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  <GlobalNamingResources>
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    <Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>

engine是核心组件,负责通过connector接收用户请求,并处理请求,将请求转发至对应的虚拟主机host上,defaulthost指定缺省的处理请求的主机名,它至少与其中呢一个host元素的name属性值是一样的
realm表示存放用户名、密码及role的数据库

XML配置文件结构
<Server>                     顶层类元素:一个配置文件中只能有一个<Server>元素,可包含多个Service。
    <Service>                顶层类元素:本身不是容器,可包含一个Engine,多个Connector。
        <Connector/>         连接器类元素:代表通信接口。
           <Engine>   容器类元素:为特定的Service组件处理所有客户请求,可包含多个Host。
              <Host>    容器类元素:为特定的虚拟主机处理所有客户请求,可包含多个Context。
                 <Context>   容器类元素:为特定的Web应用处理所有客户请求。
                 </Context>
               </Host>
              </Engine>
     </Service>
</Server>

Tomcat Server处理一个http请求的过程
假设来自客户的请求为:
http://localhost:8080/wsota/wsota_index.jsp
请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
Engine获得请求localhost/wsota/wsota_index.jsp,匹配它所拥有的所有虚拟主机Host
Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
localhost Host获得请求/wsota/wsota_index.jsp,匹配它所拥有的所有Context
Host匹配到路径为/wsota的Context(如果匹配不到就把该请求交给路径名为"“的Context去处理)
path=”/wsota"的Context获得请求/wsota_index.jsp,在它的mapping table中寻找对应的servlet
Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
Context把执行完了之后的HttpServletResponse对象返回给Host
Host把HttpServletResponse对象返回给Engine
Engine把HttpServletResponse对象返回给Connector
Connector把HttpServletResponse对象返回给客户browser

在这里插入图片描述

自定义目录

修改server.xml文件中的host元素
#appBase 定义站点目录
#docBase 定义应用目录
#Context path 指出你的访问路径(虚拟应用名,可为空)
#Context docBase 指定你的存放路径
#debug 为设定dedug的登记,0提供最少的信息,9提供最多的信息
#reloadable=true 当web.xml或者class有改动的是后续都会自动更新加载,不需要从新启动服务
#crosscontext=“true” 表示配置的不同context共享一个session
#unpackWARs 是否自动解压war包
#autoDeploy 是否自动部署(热部署)

<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Context path="/shop" docBase="/data/project" debug="0" reloadable="false" crossContext="true">
</Context>
</Host>

appBase 这个目录表示:
这个目录下面的子目录将自动被部署为应用(autoDeploy=“true”)
这个目录下的war文件将被自动解压缩并部署为应用(unpackWARs=“true”)
这个目录下的子目录,会当做单独的虚拟目录,或者叫应用
如果不想使用Tomcat下的webapp目录路,则appBase下面加一行docBase,把路径配置到docBase中,把appBase为空就可以了

目录浏览

修改 conf/web.xml文件,将listings改为true(调试使用,生产环境不建议开启)
效果如下图:
在这里插入图片描述

如果不开启,是看不了的,会报错,如下图
在这里插入图片描述

多实例(一个主机运行多个Tomcat)

演示

[root@localhost ~]# cp -ra /usr/local/apache-tomcat-8.5.35/ /usr/local/apache-tomcat-8.5.35-2
[root@localhost ~]# vim /usr/local/apache-tomcat-8.5.35-2/conf/server.xml 
修改实例停止端口 原来是8005 这个改成8006吧
<Server port="8006" shutdown="SHUTDOWN">
修改连接器端口 原来为8009/8443  改成 8010 8444
    <Connector port="8010" protocol="AJP/1.3" redirectPort="8444" />
 修改web服务器端口 原来是8080 改成8081
     <Connector port="8081" protocol="HTTP/1.1"

启动第二个实例
[root@localhost ~]# /usr/local/apache-tomcat-8.5.35-2/bin/startup.sh 

JVM内存监控

自定义一个监控页面,通过web查看运行性能(类似phpinfo)
server.xml如下设置
在这里插入图片描述

[root@localhost apache-tomcat-8.5.35]# vim /test/meminfo.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@localhost apache-tomcat-8.5.35]# firefox 192.168.43.249:8080/shop/meminfo.jsp
在这里插入图片描述

远程监控

Tomcat开启JMX远程调试功能

  1. 修改bin/catalina.sh ,找到“#—–Execute The Requested Command”,在它上边添加
[root@localhost apache-tomcat-8.5.35]# vim bin/catalina.sh 
CATALINA_OPTS="-Djava.rmi.server.hostname=192.168.43.249 
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=8080
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=true"

端口号为本机Tomcat的监听端口,最后一项表明启用登陆认证
  1. 配置认证,配置jmxremote.access和jmxremote.password 进入默认按照jdk的目录
[root@localhost jdk1.8.0_201]# cd /usr/local/jdk1.8.0_201/jre/lib/management/
[root@localhost management]# cp jmxremote.password.template jmxremote.password
[root@localhost management]# vim jmxremote.password
取消注释并修改
monitorRole  123456
controlRole   123456

[root@localhost management]# vim jmxremote.access 
可以看到配置文件里
monitorRole   readonly
controlRole   readwrite \
controlRole具有更高权限

限制口令文件读取权限
[root@localhost management]# chmod 600 jmxremote.password jmxremote.access 
  1. 重启Tomcat
  2. 客户端安装jdk,使用jdk自带的jconsole控制台进行连接,本次操作是使用另外一台主机访问Tomcat主机(192.168.43.249)
    [root@localhost apache-tomcat-8.5.35]# /usr/local/jdk1.8.0_201/bin/jconsole
    在这里插入图片描述
    在这里插入图片描述

后台

app manager

做这个的时候要把catalina.sh里边写入的东西删除掉,否则Tomcat无法访问到页面

  1. 修改 webapps/manager/META-INF/context.xml文件,允许哪些ip可以访问manager服务
[root@localhost apache-tomcat-8.5.35]# vim webapps/manager/META-INF/context.xml 
<Context antiResourceLocking="false" privileged="true" >
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="192.168.43.*" />
  <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>

allow=“127.0.0.1|192.168.0.1” /> 这样写标书允许192.168.0.1和127.0.0.1访问

  1. 修改conf/tomcat-users.xml文件,配置manager角色、用户名及密码
[root@localhost apache-tomcat-8.5.35]# vim conf/tomcat-users.xml 
把原来配置文件底部的内容取消注释并修改
<tomcat-users>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<user username="manager" password="123456" roles="manager-gui"/>
<user username="managerscript" password="123456" roles="manager-script"/>
</tomcat-users>

在这里插入图片描述

  • manager-gui #允许访问html接口(即URL路径为/manager/html/*)
  • manager-script #允许访问纯文本接口(即URL路径为/manager/text/*)
  • manager-jmx #允许访问JMX代理接口(即URL路径为/manager/jmxproxy/*)
  • manager-status #允许访问Tomcat只读状态页面(即URL路径为/manager/status/*)

manager-gui、manager-script、manager-jmx均具备manager-status权限,无需添加manager-status权限,即可直接访问路径/manager/status/*

  1. 重启Tomcat并访问
[root@localhost apache-tomcat-8.5.35]# ./bin/shutdown.sh 
[root@localhost apache-tomcat-8.5.35]# ./bin/startup.sh 
[root@localhost apache-tomcat-8.5.35]# firefox 192.168.43.249:8080/manager/html/

访问url出现下面的页面,填入用户名和密码进行访问
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

从app manager后台中,可以实现管理应用运行状态,选择是否部署、会话管理、信息状态查看、部署war包等动作

查看状态
firefox 192.168.43.249:8080/manager/status/
在这里插入图片描述

host manager

主机管理,主要用于管理域名

修改允许访问的ip

[root@localhost apache-tomcat-8.5.35]# vim webapps/host-manager/META-INF/context.xml 
改成所有 ^.*$

修改conf/tomcat-users.xml文件 添加配置admin角色、用户名及密码

[root@localhost apache-tomcat-8.5.35]# vim conf/tomcat-users.xml 
添加内容如下
  <role rolename="admin-gui"/>
  <role rolename="admin-script"/>
  <user username="admin" password="123456" roles="admin-gui"/>
  <user username="adminscript" password="123456" roles="admin-script"/>

在这里插入图片描述

重启Tomcat

[root@localhost apache-tomcat-8.5.35]# ./bin/shutdown.sh 
[root@localhost apache-tomcat-8.5.35]# ./bin/startup.sh 
[root@localhost apache-tomcat-8.5.35]# firefox 192.168.43.249:8080
在主页右侧点击Host Manager

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

部署

后台部署

通过后台AppManager的web页面进行部署
在这里插入图片描述
这里有两种部署方式 一种是“war file to deploy”,另一种是“deploy directory or war file located on server”

先演示第二种,点击browse,选择war包
在这里插入图片描述
在这里插入图片描述
然后点击deploy,会弹出新的页面,如下图,表示应用已经部署完成
在这里插入图片描述
访问应用:firefox 192.168.43.249:8088/bdqnweb/ 后来把监听端口改为8088了,如果是8080就写8080
在这里插入图片描述
删掉应用目录,重新使用第一种方法部署

[root@localhost testdir]# cd /usr/local/apache-tomcat-8.5.35/webapps/
[root@localhost webapps]# ls
bdqnweb  bdqnweb.war  docs  examples  host-manager  manager  ROOT
[root@localhost webapps]# rm -rf bdqnweb

如图填写,点击deploy
在这里插入图片描述
弹出新的页面,表示部署OK,可以访问测试一下
在这里插入图片描述
在这里插入图片描述

热部署

tomcat的热部署实现原理:tomcat启动的时候会有启动一个线程每隔一段时间会去判断应用中加载的类是否发生变法(类总数的变化,类的修改),如果发生了变化就会把应用的启动线程停止掉,清除引用,并且把加载该应用的WebappClassLoader设为null,然后创建一个新的WebappClassLoader来重新加载应用。

<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">

reloadable的作用是当你修改了jsp之后会自动编译class文件,等于即时生效,但是代价不低,适合本地开发调试,一般在开发阶段将reloadable的属性设置为true,有助于调试servlet和其他的class文件,但是由于这样会增加服务器的运行负载,损耗系统性能,在项目运行阶段将它设置为false

war包部署

  • 直接将web项目文件(一般是复制生成的war包)复制到Tomcat的webapps目录
  • 如果Tomcat没有开启自解压,则将war包解压到webapps目录

解压命令jar(解压到当前目录)
jar -xf bdqnweb.war
war包也可以使用unzip解压,使用unzip命令的时候,可以指定解压目录

安全

端口防护

修改目标端口为不易猜测的端口,降低自动扫描软件发现到的几率

后台管理

  • 删除默认的管理后台(如果不需要使用),降低被爆破和提权的风险
  • 删除webapp下的host-manager和manager目录

禁用目录浏览

修改 conf/web.xml文件,将listings改为false

隐藏信息

尽量避免暴露服务器的版本信息,隐藏错误页面。在配置中对一些常见的错误进行重定向,避免出现错误时Tomcat默认显示的错误页面暴露服务器和版本信息;必须确保程序根目录下的错误页面已经存在;

vim conf/web.xml
添加内容
<error-page>
<error-code>404</error-code>
<location>/notfound.jsp</location>
</error-page>
重启Tomcat,测试一下
firefox 192.168.43.249:8088/aaaaaaaaaaaaaaa

注意:这里的意思是说,如果是404的错误就找/目录下的notfound.jsp,所以一定要知道自己的网页根目录在哪,并在这个目录下创建notfound.jsp页面,页面内容自己编辑 网页根目录是server.xml文件中 host 标签下的context标签里的docBase
在这里插入图片描述
访问上边的url,效果如下图
在这里插入图片描述

上边web.xml中只写了404报错的,其他常见报错也可以写,比如

<error-page>
<error-code>403</error-code>
<location>/forbidden.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/notfound.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/systembusy.jsp</location>
</error-page>

脚本权限收回

去除其他用户对Tomcat的bin目录下的 shutdown.sh、startup.sh、catalina.sh的可执行权限,防止其他用户有Tomcat的权限
chmod -R 744 /usr/local/apache-tomcat-8.5.35/bin/

日志规范

开启Tomcat默认访问日志中的referer和user-agent记录,开启这两个是为了一旦出现安全问题,能够更好的根据日志进行问题排查

[root@localhost apache-tomcat-8.5.35]# vim conf/server.xml 
原来是这样:
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
修改后的样子:
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t %r %s %b %{Referer}i %{User-Agent}i %D" />

日志

使用cronolog对日志每天切割

  1. 下载安装cronolog日志切割工具
[root@localhost ~]# wget http://cronolog.org/download/cronolog-1.6.2.tar.gz
[root@localhost ~]# tar -zxf cronolog-1.6.2.tar.gz 
[root@localhost ~]# cd cronolog-1.6.2/
[root@localhost cronolog-1.6.2]# ./configure && make && make install 
[root@localhost cronolog-1.6.2]# which cronolog 
/usr/local/sbin/cronolog
  1. 编辑Tomcat的bin/catalina.sh
注释原有的touch方式的catalina.out的产生
[root@localhost cronolog-1.6.2]# cd /usr/local/apache-tomcat-8.5.35/
[root@localhost apache-tomcat-8.5.35]# sed -i 's/touch "$CATALINA_OUT"/#touch "$CATALINA_OUT"/g' bin/catalina.sh 

使用自定义文件名+日期格式,并且使用cronolog每天进行切分
[root@localhost apache-tomcat-8.5.35]# sed -i 's/>> "$CATALINA_OUT" 2>\&1 "&"/2>\&1 |\/usr\/local\/sbin\/cronolog "$CATALINA_BASE\/logs\/catalina-bdqn-%Y-%m-%d.log" \&/g' bin/catalina.sh

优化

JVM设置

在Tomcat中设置JVM参数
修改bin/catalina.sh文件设置参数(在第一行#!/bin/sh下写),增加

set JAVA_OPTS=-Dfile.encoding=UTF-8
-server 
-Xms1024M 
-Xmx1024M 
-XX:NewSize=512M 
-XX:MaxNewSize=1024M 
-XX:PermSize=256M
-XX:MaxPermSize=356M  
-XX:NewRatio=2
-XX:MaxTenuringThreshold=50
-XX:DisableExplicitGC 

参考下述建议,根据自身硬件情况和业务情况设定

详解
-server:一定要作为第一个参数,在多个 CPU 时性能佳,还有一种叫 -client 的模式,特点是启动速度比较快,但运行时性能和内存管理效率不高,通常用于客户端应用程序或开发调试,在 32 位环境下直接运行 Java 程序默认启用该模式。Server 模式的特点是启动速度比较慢,但运行时性能和内存管理效率很高,适用于生产环境,在具有 64 位能力的 JDK 环境下默认启用该模式。在Windows上,缺省的情况下默认是client模式,如果要使用server模式,需要在启动虚拟机时加-server参数,以获得高性能,对服务器应用,推荐采用server模式,尤其是多个CPU的系统。在Linux或者Solaris上缺省则采用server模式。

-Xms:表示 JVM初始内存大小,也可以说是Java 初始化堆的大小,-Xms 与-Xmx 设成一样的值,避免 JVM 反复重新申请内存,导致性能大起大落,默认值为物理内存的 1/64

-Xmx:表示最大 Java 堆大小,当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃,因此一般建议堆的最大值设置为可用内存的最大值的80%。如何知道我的 JVM 能够使用最大值,使用 java -Xmx512M -version 命令来进行测试,然后逐渐的增大 512 的值,如果执行正常就表示指定的内存大小可用,否则会打印错误信息,默认值为物理内存的

-Xmn:设置JVM最小内存(128-256就够了,一般不设置)

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

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

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

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

-XX:NewRatio:改变新旧空间的比例,意思是新空间的尺寸是旧空间的1/8(默认为8)

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

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

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

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

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

线程池设置

在Tomcat中,每一个用户请求都是 一个线程,所以可以使用线程池提高性能。
在配置文件server.xml的connector中引用,可以设置最大线程数为500,启动时最小线程为4,如下设置

在service标签下添加内容一个标签exector
      <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="500" minSpareThread="4"/>
在connector标签的http1.1下边添加:
               executor="tomcatThreadPool"

在这里插入图片描述
Excutor重要参数说明:

  1. name:共享线程池的名字,这是connector为了共享线程池要引用的名字,改名字必须唯一
  2. namePrefix:在JVM上,每运行线程都可以有一个name字符串,这一属性为线程池中每个线程的name字符串设置了一个前缀,Tomcat将把线程号追加到这一前缀后面,默认值为tomcat-exec-
  3. maxThreads:该线程池可以容纳的最大线程数,默认200
  4. maxIdleTime:在Tomcat关闭一个空闲线程之前,允许空闲线程持续的时间(单位为毫秒)。只有当前活跃的线程数大于minSpareThread的值,才会关闭空闲进程,默认值60000,一分钟
  5. minSpareThreads:Tomcat应该始终打开的最小不活跃线程数,默认25
  6. threadPriority:线程的等级

Connector重要参数说明

  1. executor:表示使用参数值对应的线程池
  2. minProcessors:服务器启动时创建的处理请求的线程数
  3. maxProcessors:最大可以创建的处理请求的进程数
  4. acceptCount:指定当前所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求不予处理。

处理方式

Tomcat支持三种接收请求的方式:BIO NIO APR

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值