JAVA企业级应用服务器之TOMCAT

第一章 Tomcat简介

  • Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache,Sun和其他一些公司及个人共同开发而成。
  • Tomcat服务器是一给免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP程序的首选。
  • Tomcat和Nginx,Apache(httpd),lighttpd等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Nginx/Apache服务器。

对比php软件,区别?

目前Tomcat最新版本为10.0。Java容器还有resin,weblogic等。

 

第二章 Tomcat安装

   2.1软件准备

    JDK下载:https://www.oracle.com/java/technologies/downloads/#java8

    Tomcat下载:http://tomcat.apache.org/

   2.2部署java环境jdk

    

复制代码
#jdk的解压安装
[root@TOMCAT ~]# tar xf jdk-8u341-linux-x64.tar.gz -C /usr/local/
[root@TOMCAT ~]# ln -s /usr/local/jdk1.8.0_341/ /usr/local/jdk

#配置java环境变量
[root@TOMCAT ~]# sed -i.ori '$a export JAVA_HOME=/usr/local/jdk\nexport PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH\nexport CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar' /etc/profile
[root@TOMCAT ~]# tail -3 /etc/profile
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar

#让java环境变量立刻生效
[root@TOMCAT ~]# source /etc/profile

#检查java环境安装情况
[root@TOMCAT ~]# which java
/usr/local/jdk/bin/java
[root@TOMCAT ~]# java -version     #出现以下信息表示部署成功
java version "1.8.0_341"
Java(TM) SE Runtime Environment (build 1.8.0_341-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.341-b10, mixed mode)
复制代码

关于上面那个sed命令的说明:

sed -i.ori :-i表示对文件本身操作,.ori表示修改的同时备份源文件

a:表示文件内容的最后一行,a表示在下面进行数据插入

\n:表示插入数据时换行

   2.3安装Tomcat

复制代码
#解压安装Tomcat
(这里使用Tomcat9版本,10版本无法安装jpress,如有安装解决办法请赐教)
[root@TOMCAT ~]# tar xf apache-tomcat-9.0.65.tar.gz -C /usr/local/
[root@TOMCAT ~]# ln -s /usr/local/apache-tomcat-9.0.65/ /usr/local/tomcat

#配置Tomcat环境变量
[root@TOMCAT ~]# echo 'export TOMCAT_HOME=/usr/local/tomcat' >> /etc/profile
[root@TOMCAT ~]# source /etc/profile

#对jdk及Tomcat安装目录递归授权root
[root@TOMCAT ~]# chown -R root.root /usr/local/jdk/ /usr/local/tomcat/

#检查环境变量情况
[root@TOMCAT ~]# tail -4 /etc/profile
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
export TOMCAT_HOME=/usr/local/tomcat
复制代码

   2.4Tomcat目录介绍

复制代码
[root@TOMCAT ~]# cd  /usr/local/tomcat/
[root@TOMCAT tomcat]# tree -L 1
.
├── bin   #用以启动,关闭Tomcat或者其他功能的脚本(.bat文件和.sh文件)
├── BUILDING.txt
├── conf   #用以配置Tomcat的XML及DTD文件
├── CONTRIBUTING.md
├── lib   #存放web应用能访问的JAR包
├── LICENSE
├── logs   #Catalina和其他Web应用程序的日志文件
├── NOTICE
├── README.md
├── RELEASE-NOTES
├── RUNNING.txt
├── temp   #临时文件
├── webapps   #Web应用程序跟目录
└── work   #用以产生有JSP编译出的Servlet的.java和.class文件

7 directories, 7 files

[root@TOMCAT tomcat]# cd webapps/
[root@TOMCAT webapps]# ll
total 4
drwxr-x--- 15 root root 4096 Aug 24 11:24 docs   #tomcat帮助文档
drwxr-x---  7 root root   99 Aug 24 11:24 examples #web应用实例
drwxr-x---  6 root root   79 Aug 24 11:24 host-manager   #管理
drwxr-x---  6 root root  114 Aug 24 11:24 manager   #管理
drwxr-x---  3 root root  223 Aug 24 11:24 ROOT   #默认网站跟目录
复制代码

    2.5启动Tomcat

启动程序:/usr/local/tomcat/bin/startup.sh

关闭程序:/usr/local/tomcat/bin/shutdown.sh

复制代码
[root@TOMCAT webapps]# /usr/local/tomcat/bin/startup.sh   #程序启动 
Using CATALINA_BASE:   /usr/local/tomcat   #检查环境变量CATALINA_BASE
Using CATALINA_HOME:   /usr/local/tomcat   #检查环境变量CATALINA_HOME
Using CATALINA_TMPDIR: /usr/local/tomcat/temp   #检查环境变量CATALINA_TMPDIR
Using JRE_HOME:        /usr/local/jdk   #检查环境变量JRE_HOME
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.

[root@TOMCAT webapps]# netstat -antup | grep java
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      12929/java          
tcp6       0      0 :::8080                 :::*                    LISTEN      12929/java 
复制代码

   2.6访问网站

网址:192.168.200.51:8080(访问时请注意关闭iptables)

复制代码
#查看Tomcat的日志
[root@TOMCAT webapps]# cd /usr/local/tomcat/logs/
[root@TOMCAT logs]# ls
catalina.2022-08-24.log      localhost.2022-08-24.log
catalina.out                 localhost_access_log.2022-08-24.txt
host-manager.2022-08-24.log  manager.2022-08-24.log
[root@TOMCAT logs]# cat catalina.out 
24-Aug-2022 17:58:06.319 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name:   Apache Tomcat/9.0.65
24-Aug-2022 17:58:06.347 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Jul 14 2022 12:28:53 UTC
24-Aug-2022 17:58:06.347 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 9.0.65.0
24-Aug-2022 17:58:06.347 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
24-Aug-2022 17:58:06.347 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            3.10.0-1062.el7.x86_64
24-Aug-2022 17:58:06.347 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
24-Aug-2022 17:58:06.347 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/local/jdk1.8.0_341/jre
24-Aug-2022 17:58:06.347 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           1.8.0_341-b10
24-Aug-2022 17:58:06.347 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Oracle Corporation
24-Aug-2022 17:58:06.347 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /usr/local/apache-tomcat-9.0.65
24-Aug-2022 17:58:06.347 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/apache-tomcat-9.0.65
24-Aug-2022 17:58:06.349 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
24-Aug-2022 17:58:06.349 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
24-Aug-2022 17:58:06.349 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
24-Aug-2022 17:58:06.349 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
24-Aug-2022 17:58:06.349 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
24-Aug-2022 17:58:06.349 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
24-Aug-2022 17:58:06.349 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
24-Aug-2022 17:58:06.349 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
24-Aug-2022 17:58:06.349 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
24-Aug-2022 17:58:06.350 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The Apache Tomcat Native library which allows using OpenSSL was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
24-Aug-2022 17:58:06.953 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
24-Aug-2022 17:58:07.017 INFO [main] org.apache.catalina.startup.Catalina.load Server initialization in [965] milliseconds
24-Aug-2022 17:58:07.111 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
24-Aug-2022 17:58:07.111 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet engine: [Apache Tomcat/9.0.65]
24-Aug-2022 17:58:07.117 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-9.0.65/webapps/ROOT]
24-Aug-2022 17:58:07.464 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-9.0.65/webapps/ROOT] has finished in [346] ms
24-Aug-2022 17:58:07.464 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-9.0.65/webapps/docs]
24-Aug-2022 17:58:07.488 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-9.0.65/webapps/docs] has finished in [23] ms
24-Aug-2022 17:58:07.488 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-9.0.65/webapps/examples]
24-Aug-2022 17:58:07.887 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-9.0.65/webapps/examples] has finished in [399] ms
24-Aug-2022 17:58:07.888 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-9.0.65/webapps/host-manager]
24-Aug-2022 17:58:07.909 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-9.0.65/webapps/host-manager] has finished in [22] ms
24-Aug-2022 17:58:07.909 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/apache-tomcat-9.0.65/webapps/manager]
24-Aug-2022 17:58:07.935 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/apache-tomcat-9.0.65/webapps/manager] has finished in [26] ms
24-Aug-2022 17:58:07.954 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
24-Aug-2022 17:58:08.028 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [1010] milliseconds
复制代码

第三章 Tomcat的配置文件

   3.1 Tomcat配置文件

复制代码
[root@TOMCAT logs]# cd /usr/local/tomcat/conf/
[root@TOMCAT conf]# ll -h
total 232K
drwxr-x--- 3 root root   23 Aug 24 17:58 Catalina
-rw------- 1 root root  13K Jul 14 20:28 catalina.policy
-rw------- 1 root root 7.2K Jul 14 20:28 catalina.properties
-rw------- 1 root root 1.4K Jul 14 20:28 context.xml
-rw------- 1 root root 1.2K Jul 14 20:28 jaspic-providers.xml
-rw------- 1 root root 2.3K Jul 14 20:28 jaspic-providers.xsd
-rw------- 1 root root 4.1K Jul 14 20:28 logging.properties
-rw------- 1 root root 7.5K Jul 14 20:28 server.xml   #主配置文件
-rw------- 1 root root 2.7K Jul 14 20:28 tomcat-users.xml   #Tomcat管理用户配置文件
-rw------- 1 root root 2.5K Jul 14 20:28 tomcat-users.xsd
-rw------- 1 root root 169K Jul 14 20:28 web.xml
复制代码

   3.2Tomcat管理

测试功能,生产环境不要用:

Tomcat管理功能用于对Tomcat自身以及部署在Tomcat上的应用进行管理的Web应用。在默认情况下是处于禁用状态的。如果需要开启这个功能,就需要配置管理用户,即配置前面说过的tomcat-user.xml。

复制代码
#找到配置文件的第56行
[root@TOMCAT conf]# cat -n /usr/local/tomcat/conf/tomcat-users.xml | sed -n '56p'
    56    </tomcat-users>

#在56行上加入如下三行代码
[root@TOMCAT conf]# tail -4 /usr/local/tomcat/conf/tomcat-users.xml   <role rolename="manager-gui"/>   #加入此行
  <role rolename="admin-gui"/>   #加入此行
  <user username="tomcat" password="tomcat" roles="manager-gui,admin-gui"/>   #加入此行
</tomcat-users>

#重启tomcat服务
[root@TOMCAT conf]# /usr/local/tomcat/bin/shutdown.sh 
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/jdk
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
[root@TOMCAT conf]# /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/local/jdk
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.
复制代码

在浏览器中输入http://192.168.200.51:8080/manager/status进行TOMCAT管理页面

默认的tomcat的管理控制台只能在安装tomcat这台机器上访问,如果使用其它机器访问,就会出现如上错误。

如果想要在别的IP上访问管理控制台,需要做如下操作

  • 首先需要去tomcat的安装目录下的webapps/manager/META-INF,找到context.xml文件
  • 注释掉其中权限的限制

  • 保存文件后,重启tomcat,然后就可以访问到manager控制台了
  • 登陆验证信息:账号:tomcat 密码:tomcat

   3.3Tomcat主配置文件server.xml详解

   3.3.1server.xml组件类别

  • 顶级组件:位于整个配置的顶层,如server。
  • 容器类组件:可以包含其他组件的组件,如service,engine,host,context
  • 连接器组件:连接用户请求至tomcat,如connector。
  • 被嵌套类组件:位于一个容器当中,不能包含其他组件,如Valve,logger
复制代码
<server>
        <service>
        <connector />
        <engine>
        <host>
        <context></context>
        </host>
        <host>
        <context></context>
        </host>
        </engine>
        </service>
    </server>
复制代码

   3.3.2组件详解

  • engine:核心容器组件,catalina引擎,负责通过connector接收用户请求,并处理请求,将请求转至对应的虚拟主机host。
  • host:类似于httpd中的虚拟主机,一般而言支持基于FQDN的虚拟主机。
  • context:定义一个应用程序,是一个最内层的容器类组件(不能再嵌套)。配置context的主要目的指定对应对的webapp的根目录,类似于httpd的alias,其还能为webapp指定额外的属性,如部署方式等。
  • connector:接收用户请求,类似于httpd的listen配置监听端口。
  • service(服务):将connector关联至engine,因此一个service内部可以有多个connector,但只能又一个引擎engine。service内部有两个connector,一个engine。因此,一般情况下一个server内部只有一个service,一个service内部只有一个engine,但一个service内部可以有多个connector。
  • server:表示一个运行于JVM中的tomcat实例。
  • Valve:阀门,拦截请求并在将其转至对应的webapp前进行某种处理操作,可以用于任何容器中,比如记录日志(access log valve),基于IP做访问控制(remote address filervalve)。
  • logger:日志记录器,用于记录组件内部的状态信息,可以用于除context外的任何容器中。
  • realm:可以用于任意容器类的组件中,关联一个用户认证库,实现认证和授权。可以关联的认证库有两种:UserDatabaseRealm,MemoryRealm和JDBCRealm。
  • UserDatabaseRealm:使用JNDI自定义的用户认证库。
  • MemoryRealm:认证信息定义在tomcat-users.xml中。
  • JDBCRealm:认证信息定义在数据库中,并通过JDBC连接至数据库中查找认证用户。

   3.3.3配置文件注释

 

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!-- Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
 -->
<!--
<Server>元素代表整个容器,是Tomcat实例的顶层元素。由org.apache.catalina.Server接口来定义。它包含一个<Service>元素。并且它不能作为任何元素的子元素。
  port指定Tomcat监听shutdown命令端口。终止服务器运行时,必须在Tomcat服务器所在的机器上发出shutdown命令。该属性是必须的。
  shutdown指定终止Tomcat服务器运行时,发给Tomcat服务器的shutdown监听端口的字符串。该属性必须设置
-->
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!-- APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <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>

  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
   -->
<!--service服务组件-->
  <Service name="Catalina">
<!--
  connector:接收用户请求,类似于httpd的listen配置监听端口。
  port指定服务器端要创建端口号,并在整个端口监听来自客户端的请求。
  address:指定连接器监听的地址,默认为所有地址(即0.0.0.0)
  protocol连接器使用的协议,支持HTTP和AJP.AJP(Apache Jserv Protocol)专用于tomcat与apache建立通信的,在httpd反向代理用户请求至tomcat时使用(可见Nginx反向代理时不可用AJP协议)。
  minProcessors服务器启动时创建的处理请求的线程数
  maxProcessors最大可以创建的处理请求的线程数
  enableLookups如果为true,则可以通过调用request.getRemoteHost()进行DNS查询来得到远程客户端的实际主机名,若为false则不进行DNS查询,而是返回其ip地址
  redirectPort指定服务器正在处理http请求时收到了一个SSL传输请求后重定向的端口号
  acceptCount指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理
  connectionTimeout指定超时的时间数(以毫秒为单位)
-->

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->


    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
    -->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443
         This connector uses the NIO implementation. The default
         SSLImplementation will depend on the presence of the APR/native
         library and the useOpenSSL attribute of the AprLifecycleListener.
         Either JSSE or OpenSSL style configuration may be used regardless of
         the SSLImplementation selected. JSSE style configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->
    <!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
         This connector uses the APR/native implementation which always uses
         OpenSSL for TLS.
         Either JSSE or OpenSSL style configuration may be used. OpenSSL style
         configuration is used below.
    -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <!--
    <Connector protocol="AJP/1.3"
               address="::1"
               port="8009"
               redirectPort="8443" />
    -->

    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
<!--engine,核心容器组建,catalina引擎,负责通过connector接收用户请求,并处理请求,将请求转至对应的虚拟主机host
  defaultHost指定缺省的处理请求的主机名,它至少与其中的一个host元素的name属性值是一样的
-->
    <Engine name="Catalina" defaultHost="localhost">

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
<!--Realm表示存放用户名,密码及role的数据库-->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>
<!--
  host表示一个虚拟主机
  name指定主机名
  appBase应用程序基本目录,即存放应用程序的目录。一般为appBase="webapps",相对于CATALINA_HOME而言的,也可以写绝对路径。
  autoDeploy:在tomcat启动时,是否自动部署。
  xmlValidation:是否启动xml的校验功能,一般xmlValidation="false"。
  xmlNamespaceAware:检测名称空间,一般xmlNamespaceAware="false"-->

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

        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
<!--
  Context表示一个web应用程序,通常为WAR文件
  docBase应用程序的路径或者是WAR文件存放的路径,也可以使用相对路径,起始路径为此Context所属Host中appBase定义的路径。
  path表示此web应用程序的url的前缀,这样请求的url为http://localhost:8080/path/****
  reloadable这个属性非常重要,如果为true,则tomcat会自动检测应用程序的/WEB-INF/lib和/WEB-INF/classes目录的变化,自动装载新的应用程序,可以在不重启tomcat的情况下改变应用程序
-->
        <Context path="" docBase="" debug=""/>
        <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>
复制代码

 第四章 WEB站点部署

上线的代码有两种方式,第一种方式是直接将程序目录放在webapps目录下面。第二种方式是使用开发工具将程序打包成war包,然后上传到webapps目录下面。下面我们见识一下这种方式。

   4.1使用war包部署web站点

复制代码
#部署war包
[root@TOMCAT ~]# ls -l memtest.war 
-rw-r--r-- 1 root root 643 Oct 24  2017 memtest.war   #将此war包拷贝到服务器中
[root@TOMCAT ~]# cp memtest.war /usr/local/tomcat/webapps/
[root@TOMCAT ~]# ls /usr/local/tomcat/webapps/
docs  examples  host-manager  manager  memtest.war  ROOT
#重启tomcat服务
[root@TOMCAT ~]# /usr/local/tomcat/bin/shutdown.sh 
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/jdk
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
[root@TOMCAT ~]# /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/local/jdk
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.
[root@TOMCAT ~]# netstat -antup | grep java
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      1345/java           
tcp6       0      0 :::8080                 :::*                    LISTEN      1345/java 

#查看war包的解压缩情况
[root@TOMCAT ~]# ls /usr/local/tomcat/webapps/
docs  examples  host-manager  manager  memtest  memtest.war  ROOT   #war包已经被解压出来了
复制代码

用浏览器访问:http://192.168.200.51:8080/memtest/meminfo.jsp如下:

   4.2自定义默认网站目录

上面访问的网址为:http://192.168.200.51:8080/memtest/meminfo.jsp

现在改变访问的格式为:http://192.168.200.51:8080/meminfo.jsp

方法一:

将meminfo.jsp或其他程序放在tomcat/webapps/ROOT目录下即可。因为默认网站跟目录为tomcat/webapps/ROOT

方法二:

复制代码
[root@TOMCAT ~]# vim /usr/local/tomcat/conf/server.xml

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
          <Context path="" docBase="/usr/local/tomcat/webapps/memtes
t" debug="0" reloadable="false" crossContext="true"/>   #在这里添加一行代码限定web站点的根目录路径
[root@TOMCAT ~]# /usr/local/tomcat/bin/shutdown.sh 
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/jdk
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
[root@TOMCAT ~]# /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/local/jdk
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.
复制代码

第五章 Tomcat多实例及集群架构

   5.1 Tomcat多实例

    5.1.1复制Tomcat目录

[root@TOMCAT ~]# cd /usr/local/
[root@TOMCAT local]# ls
apache-tomcat-9.0.65  games    jdk1.8.0_341  libexec  src
bin                   include  lib           sbin     tomcat
etc                   jdk      lib64         share
[root@TOMCAT local]# cp -a apache-tomcat-9.0.65/ tomcat9_1
[root@TOMCAT local]# cp -a apache-tomcat-9.0.65/ tomcat9_2

    5.1.2修改多实例配置文件

复制代码
#创建多实例的网页根目录(生产中多实例都为同一套代码)
[root@TOMCAT local]# mkdir -p /data/www/www/ROOT

#将网页程序拷贝到多实例根目录ROOT下
[root@TOMCAT local]# cp /usr/local/tomcat/webapps/memtest/meminfo.jsp /data/www/www/ROOT/

#修改多实例配置文件的以下三行
[root@TOMCAT local]# cat -n /usr/local/tomcat/conf/server.xml | sed -n '22p;69p;151p'
    22    <Server port="8005" shutdown="SHUTDOWN">   #管理端口及停止命令
    69        <Connector port="8080" protocol="HTTP/1.1"   #对外提供服务的端口
   151          <Host name="localhost"  appBase="webapps"   #网站域名及网页根目录路径

#修改第一个多实例配置文件

[root@TOMCAT local]# sed -i '22s#8005#8011#;69s#8080#8081#;151s#appBase=".*"#appBase="/data/www/www"#' /usr/local/tomcat9_1/conf/server.xml 
[root@TOMCAT local]# sed -n '22p;69p;151p' /usr/local/tomcat9_1/conf/server.xml 
<Server port="8011" shutdown="SHUTDOWN">
    <Connector port="8081" protocol="HTTP/1.1"
      <Host name="localhost"  appBase="/data/www/www"

#修改第二个多实例配置文件

[root@TOMCAT local]# sed -i '22s#8005#8012#;69s#8080#8082#;151s#appBase=".*"#appBase="/data/www/www"#' /usr/local/tomcat9_2/conf/server.xml 
[root@TOMCAT local]# sed -n '22p;69p;151p' /usr/local/tomcat9_2/conf/server.xml 
<Server port="8012" shutdown="SHUTDOWN">
    <Connector port="8082" protocol="HTTP/1.1"
      <Host name="localhost"  appBase="/data/www/www"
复制代码

    5.1.3启动多实例

复制代码
#启动多实例服务
[root@TOMCAT ~]# /usr/local/tomcat9_1/bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat9_1
Using CATALINA_HOME:   /usr/local/tomcat9_1
Using CATALINA_TMPDIR: /usr/local/tomcat9_1/temp
Using JRE_HOME:        /usr/local/jdk
Using CLASSPATH:       /usr/local/tomcat9_1/bin/bootstrap.jar:/usr/local/tomcat9_1/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.
[root@TOMCAT ~]# /usr/local/tomcat9_2/bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat9_2
Using CATALINA_HOME:   /usr/local/tomcat9_2
Using CATALINA_TMPDIR: /usr/local/tomcat9_2/temp
Using JRE_HOME:        /usr/local/jdk
Using CLASSPATH:       /usr/local/tomcat9_2/bin/bootstrap.jar:/usr/local/tomcat9_2/bin/tomcat-juli.jar
Using CATALINA_OPTS:   
Tomcat started.

#查看多实例进程启动情况

[root@TOMCAT ~]# netstat -antup | grep java
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      1461/java           
tcp6       0      0 127.0.0.1:8011          :::*                    LISTEN      1708/java           
tcp6       0      0 127.0.0.1:8012          :::*                    LISTEN      1743/java           
tcp6       0      0 :::8080                 :::*                    LISTEN      1461/java           
tcp6       0      0 :::8081                 :::*                    LISTEN      1708/java           
tcp6       0      0 :::8082                 :::*                    LISTEN      1743/java
复制代码

浏览器可以分别访问http://192.168.200.51:8081/meminfo/jsp和http://192.168.200.51:8082/meminfo.jsp

   5.2 Tomcat集群

使用nginx+Tomcat反向代理集群

    5.2.1安装nginx

[root@TOMCAT ~]# yum -y install pcre-devel openssl-devel
[root@TOMCAT ~]# wget -q http://nginx.org/download/nginx-1.23.1.tar.gz
[root@TOMCAT ~]# useradd -s /sbin/nologin -M nginx
[root@TOMCAT ~]# tar xf nginx-1.23.1.tar.gz -C /usr/src/
[root@TOMCAT ~]# cd /usr/src/nginx-1.23.1/
[root@TOMCAT nginx-1.23.1]# ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
[root@TOMCAT nginx-1.23.1]# make && make install

    5.2.2修改nginx配置文件如下

复制代码
#创建配置文件模板
[root@TOMCAT nginx]# egrep -v "#|^$" /usr/local/nginx/conf/nginx.conf.default > /usr/local/nginx/conf/nginx.conf

#修改配置文件内容如下:
[root@TOMCAT nginx]# cat /usr/local/nginx/conf/nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream tomcat {
    server 127.0.0.1:8081;
    server 127.0.0.1:8082;
    }
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm index.jsp;
        proxy_pass http://tomcat;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

#检测语法并启动nginx
[root@TOMCAT nginx]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@TOMCAT nginx]# /usr/local/nginx/sbin/nginx 
[root@TOMCAT nginx]# netstat -antup | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      4621/nginx: master
复制代码

负载均衡效果自行测试

   5.3 使用Tomcat安装Jpress

Jpress,一个wordpress的java代替版本,使用JFinal开发,需要maven支持

复制代码
[root@TOMCAT ~]# tar xf apache-maven-3.8.6-bin.tar.gz -C /usr/local/[root@TOMCAT ~]# ln -s /usr/local/apache-maven-3.8.6/ /usr/local/maven
[root@TOMCAT ~]# tail -2 /etc/profile
export MAVEN_HOME=/usr/local/maven
export PATH="$MAVEN_HOME/bin:$PATH"
[root@TOMCAT ~]# source /etc/profile
[root@TOMCAT ~]# mvn -version   #出现这个表示成功
Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
Maven home: /usr/local/maven
Java version: 1.8.0_341, vendor: Oracle Corporation, runtime: /usr/local/jdk1.8.0_341/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-1062.el7.x86_64", arch: "amd64", family: "unix"
复制代码

因为之前自定义网站目录时修改了server.xml,添加了一行代码限定web站点的根目录路径,因此安装jpress之前需要将tomcat9_1与tomcat9_2中server.xml中添加的代码注释并重启,不然按照以下路径去安装会出错

 

将jpress-web-newest.war包放到Tomcat网站跟目录下

复制代码
#将war包放到网站根目录下
[root@TOMCAT wars]# ls -l jpress-web-newest.war 
-rw-rw-r-- 1 root root 20764271 Sep 19  2016 jpress-web-newest.war
[root@TOMCAT wars]# mv jpress-web-newest.war /data/www/www/ROOT/

#解压war包
[root@TOMCAT wars]# which jar
/usr/local/jdk/bin/jar
[root@TOMCAT wars]# cd /data/www/www/ROOT/
[root@TOMCAT ROOT]# jar xf jpress-web-newest.war    #jar是war包的解压命令
[root@TOMCAT ROOT]# ls
jpress-web-newest.war  META-INF    static     WEB-INF
meminfo.jsp            robots.txt  templates
复制代码

用浏览器访问:http://192.168.200.51/install进入jpress安装向导

特别提示:

  • 虽然,Tomcat已经打开了自动解压缩war包的功能,但是并没有重启Tomcat服务,因此,war包并没有被自动解压缩。故,我们需要通过jar命令进行解压缩,命令的参数和tar是一样的。
  • 接下来就需要为jpress安装数据库了,之后的所有流程和LNMP章节里面一样。因此,在这里就不继续操作了。

 第六章 Tomcat安全优化和性能优化

   6.1安全优化

最重要的优化为如下4项,但并不止这四种

  • 降权启动
  • telnet管理端口保护
  • ajp连接端口保护
  • 禁用管理端

具体操作如下:

(1)降权启动(同nginx优化部分的监牢模式)

降权的原则就是利用普通用户来启动Tomcat

(1)将Tomcat程序目录拷贝到普通用户的家目录下

(2)修改家目录下程序的配置文件(启动端口,检测端口等),并重新指定网页根目录路径。

(3)递归授权拷贝后的Tomcat程序的属主属组为普通用户。

(4)用su命令切换为普通用户,启动Tomcat进程

(5)此时Tomcat进程的权限为普通用户权限

(6)如果利用/etc/rc.local文件配置普通用户程序的开机启动,那么需要利用su -c临时切换身份启动。

(2)telnet管理端口保护

 

复制代码
[root@TOMCAT ~]# sed -n '22p' /usr/local/tomcat/conf/server.xml 
<Server port="8005" shutdown="SHUTDOWN">   #表示通过8005端口来接受SHUTDOWN,用来停止Tomcat进程。默认的方式是非常危险的。需要进行修改
[root@TOMCAT ~]# netstat -antup | grep java
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      1461/java   #本地8005端口接收SHUTDOWN命令           
tcp6       0      0 127.0.0.1:8011          :::*                    LISTEN      1708/java   #本地8011端口接收SHUTDOWN命令           
tcp6       0      0 127.0.0.1:8012          :::*                    LISTEN      1743/java   #本地8012端口接收SHUTDOWN命令           
tcp6       0      0 :::8080                 :::*                    LISTEN      1461/java           
tcp6       0      0 :::8081                 :::*                    LISTEN      1708/java           
tcp6       0      0 :::8082                 :::*                    LISTEN      1743/java
复制代码

Tomcat默认通过8005端口接收SHUTDOWN这个字符串来关闭Tomcat进程,但这是非常危险的,因此需要修改端口号来防护。否则,通过telnet命令即可强行关闭Tomcat进程

 

复制代码
#利用Telnet来关闭Tomcat进程
[root@TOMCAT ~]# telnet 127.0.0.1 8005   #通过telnet连接本地8005端口
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
SHUTDOWN   #发送SHUTDOWN字符串
Connection closed by foreign host.
[root@TOMCAT ~]# netstat -antup | grep java   #可以发现8005端口和8080端口的Tomcat进程没了
tcp6       0      0 127.0.0.1:8011          :::*                    LISTEN      1275/java           
tcp6       0      0 127.0.0.1:8012          :::*                    LISTEN      1302/java           
tcp6       0      0 :::8081                 :::*                    LISTEN      1275/java           
tcp6       0      0 :::8082                 :::*                    LISTEN      1302/java
复制代码

(3)ajp连接端口保护

[root@TOMCAT ~]# sed -n '116,119p' /usr/local/tomcat/conf/server.xml 
    <Connector protocol="AJP/1.3"
               address="::1"
               port="8009"
               redirectPort="8443" />
#这是AJP协议打开的端口,不需要开启这个端口,配置文件默认已经注释掉了

(4)禁用管理端

Tomcat默认在安装完成后的网页目录路由很多多余的目录,删除所有不需要用到的目录,并清空ROOT网页默认根目录下的所有东西,规避可能的代码漏洞

复制代码
[root@TOMCAT ~]# cd /usr/local/tomcat/webapps/
[root@TOMCAT webapps]# ls
docs          jpress-web-newest      memtest
examples      jpress-web-newest.war  memtest.war
host-manager  manager                ROOT
#有很多多余的东西,只留下ROOT目录,其他都删掉或者mv移走
[root@TOMCAT webapps]# ls ROOT/   #有很多多余的东西,因此清空本目录,或者都移走
asf-logo-wide.svg  bg-nav.png    index.jsp          tomcat.svg
bg-button.png      bg-upper.png  RELEASE-NOTES.txt  WEB-INF
bg-middle.png      favicon.ico   tomcat.css
复制代码

   6.2 性能优化

    6.2.1屏蔽DNS查询enableLookups="false"

DNS查询非常消耗时间,如果开启会影响Tomcat性能,因此关闭。

#默认没有,需添加配置文件如下代码段,在Connector标签位置。表示禁止DNS查询
<Connector port="8081" protocol="HTTP/1.1"
               connectionTimeout="6000" enableLookups="false" acceptCount="800"
               redirectPort="8443" />

    6.2.2jvm调优

Tomcat最吃内存,只要内存足够,这只猫就跑的很快。

如果系统资源有限,那就需要进行调优,提高资源使用率。

复制代码
#优化catalina.sh初始化脚本。在catalina.sh初始化脚本中添加一下代码:
#catalina.sh的路径为:/usr/local/tomcat/bin/catalina.sh
#此行优化代码需要加在脚本的最开始,声明位置。不要放在后边
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m"

#代码说明:
server:一定要作为第一个参数,在多个cpu时性能佳
-Xms:初始堆内存Heap大小,使用的最小内存,cpu性能高时此值应设的大一些
-Xmx:初始堆内存heap最大值,使用的最大内存
上面两个值是分配JVM的最小和最大内存,取决于硬件物理内存的大小,建议均设为物理内存的一半。
-XX:PermSize:设定内存的永久保存区域
-XX:MaxPermSize:设定最大内存的永久保存区域
-XX:MaxNewSize:
-Xss 15120 这使得JBoss每增加一个线程(thread)就会立即消耗15M内存,而最佳值应该是128K,默认值好像是512K.
+XX:AggressiveHeap 会使得 Xms没有意义。这个参数让jvm忽略Xmx参数,疯狂地吃完一个G物理内存,再吃尽一个G的swap。
-Xss:每个线程的Stack大小
-verbose:gc 现实垃圾收集信息
-Xloggc:gc.log 指定垃圾收集日志文件
-Xmn:young generation的heap大小,一般设置为Xmx的3、4分之一
-XX:+UseParNewGC: 缩短minor收集的时间
-XX:+UseConcMarkSweepGC: 缩短major收集的时间
复制代码

附录1:Linux下java/http进程高解决案例

生产环境下某台tamcat7服务器,在刚发布的时候一切都很正常,在运行一段时间后就出现CPU占用很高的问题,基本上是负载一天比一天高。诸如此类问题,请排查!

问题分析:

(1)程序属于CPU密集型,和开发沟通过,排除此类情况

(2)程序代码有问题,出现死循环,可能性极大

问题解决:

(1)开发那边无法排查代码某个模块有问题,从日志上也无法分析得出

(2)我们可尝试通过jstack命令来精确定位出现错误的代码段,从而拿给开发排查

(1)首先查找进程高的PID号(先找到是哪个PID号的进程导致的)

top -H

(2)查看这个进程所有系统调用(再找到是哪个PID号的线程导致的)

strace -p 进程的PID

(3)如果是web应用,可以继续打印该线程的堆栈信息(找出有问题的代码块)

printf "%x\n"线程的PID   #将有问题的线程的PID号转换成16进制格式

jstack 进程的PID | grep 线程PID号的十六进制格式 -A 30 #过滤出有问题的线程的堆栈信息,找出问题代码块

实际操作演示:

复制代码
[root@TOMCAT webapps]# pgrep -l java
1302 java   #java进程及对应的PID号
1525 java
4863 java
[root@TOMCAT webapps]# strace -p 1302
strace: Process 1302 attached
futex(0x7fc415dd49d0, FUTEX_WAIT, 1303, NULL   #只有一个线程,线程的PID号为1303
^Cstrace: Process 1302 detached
 <detached ...>
[root@TOMCAT webapps]# printf "%x\n" 1303   #将线程的PID号1303转换成十六进制格式
517
[root@TOMCAT webapps]# jstack 1302 | grep 517 -A 30   #追踪进程号为1302的进程的所有线程调用,从里面过滤出16进制为517的线程的代码调用情况
"main" #1 prio=5 os_prio=0 tid=0x00007fc40c00a000 nid=0x517 runnable [0x00007fc415dd2000]
   java.lang.Thread.State: RUNNABLE
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:535)   #圆括号里显示的是(代码类名:具体调用的代码行号)
    at java.net.ServerSocket.implAccept(ServerSocket.java:545)
    at java.net.ServerSocket.accept(ServerSocket.java:513)
    at org.apache.catalina.core.StandardServer.await(StandardServer.java:605)
    at org.apache.catalina.startup.Catalina.await(Catalina.java:864)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:810)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:476)

"VM Thread" os_prio=0 tid=0x00007fc40c06f000 nid=0x51b runnable 

"VM Periodic Task Thread" os_prio=0 tid=0x00007fc40c0bc000 nid=0x52c waiting on condition 

JNI global references: 320
复制代码

附录2:jstack命令(Java stack Trace)

(1)介绍

  • jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式:jstack [-l] pid
  • 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地指定java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息,如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

(2)命令格式

jstack [option] pid

jstack [option] executable core

jstack [option] [server-id@]remote-hostname-or-IP

(3)常用参数说明

1)、options:

executable Java executable from which the core dump was produced.(可能是产生core dump的java可执行程序)

core将被打印信息的core dump文件

remote-hostname-or-IP 远程debug服务的主机名或IP

server-id 唯一id,假如一台主机上多个远程debug服务

2)、基本参数:

-F:当 jstack -[l] pid没有相应的时候强制打印栈信息

-l:长列表.打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表。

-m:打印java和native c/c++框架的所有栈信息。

-h | -help:打印帮助信息

pid:需要被打印配置信息的java进程id,可以用jps查询。

零星的变得优秀,也能拼凑出星河。
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。

posted @   春风雨露  阅读(179)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示