Loading

Web服务-Tomcat

Web服务-Tomcat

1. 了解java的运行过程

不管是什么平台,只要实现了JAVA运行环境(JRE),运行JAVA程序时都能达到一样的效果(JRE由JVM和API构成。)。java源文件(.java)通过javac编译器生成字节码文件(.class),字节码文件(.class)通过JVM(Java虚拟机)中的解释器再翻译成特定机器上的机器码,然后在特定的机器上运行。编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。

Java程序运行流程


Java 解释器负责将字节码文件翻译成具体硬件环境和操作系统平台下的机器代码,以便执行。因此 Java 程序不能直接运行在现有的操作系统平台上,它必须运行在被称为 Java 虚拟机的软件平台之上。

Java 虚拟机(JVM)是运行 Java 程序的软件环境,Java 解释器是 Java 虚拟机的一部分。在运行 Java 程序时,首先会启动 JVM,然后由它来负责解释执行 Java 的字节码程序,并且 Java 字节码程序只能运行于 JVM 之上。

Java 程序通过 JVM 可以实现跨平台特性,但 JVM 是不跨平台的。也就是说,不同操作系统之上的 JVM 是不同的,Windows 平台之上的 JVM 不能用在 Linux 平台,反之亦然。

Tips:只要在不同的计算机上安装了针对特定平台的 JVM,Java 程序就可以运行,而不用考虑当前具体的硬件平台及操作系统环境,也不用考虑字节码文件是在何种平台上生成的。


2. 了解JVM、JRE、JDK

  • JVM:java 虚拟机中,运行java代码的地方
  • JRE:java Runtime Enviroment java运行环境,提供JVM环境,java命令
  • JDK:Java Development Kit java开发环境,JVM+JRE+额外功能...

image-20230328095806677

Tips:主要是通过部署JDK环境来运行,同时JDK也分为Open和Oracle版本,根据实际需求选择。


3. jsp与servlet

java将应用程序放在服务器端,客户端请求此应用程序时,服务端通过servlet类库分析http协议,将请求的应用程序在服务端执行,然后将结果组织起来返回给客户端,但此时servlet能分析的http协议非常简单,且和html的组织方式非常不友好,它要求java程序员首先得懂html开发(实际上现在还是如此,java程序员至少要懂简单的html/css/javascript等前端技术),于是后来出现了JSP类库。

JSP可以简单的将java代码嵌入在html文档中,它们能够很友好地结合,结合后的文档类型为.jsp文件。当客户端请求应用程序资源时,JSP类库负责解析.jsp文件中的jsp部分并通过jasper组件将其翻译成servlet的java源代码,然后再编译成class文件并交给JVM来执行。实际上,jsp的本就就是servlet,jsp类只不过是继承于servlet类并添加了一些和html友好结合的特性,最终它还是要翻译成servlet代码。

JSP的本质还是Servlet,每个JSP页面就是一个Servlet对象(当然也可能引用了其他servlet对象),Servlet再负责响应用户的动态请求数据(其实也包括静态数据,因为jasper翻译jsp代码时,静态标签也被翻译到servlet的java源文件中以待输出)。对于Tomcat而言,JSP页面生成的Servlet放在work路径对应的Web应用下。

tomcat可以处理动态请求,也可以处理静态资源请求。但无论是动态资源,还是静态资源的请求,都是经过servlet处理并响应给客户端的,只不过请求静态资源时使用的是默认的servlet。虽然它能像httpd和nginx一样处理静态资源,但显然,它既要处理动态请求,又要处理静态请求,压力会很大。因此tomcat前一般使用httpd或nginx专门处理静态请求,而动态请求则通过反向代理的方式代理至tomcat。


4. web服务器、web容器、应用程序服务器

web服务器提供web服务,主要处理http请求并响应给客户端,并可以将动态请求委托给其他程序,如cgi脚本、jsp脚本、asp脚本等进行处理。

web容器即servlet容器主要负责处理基于http请求的动态jsp内容。EJB容器主要提供和后端数据库服务、其他服务进行交互的功能。

应用服务器通常来说包括servlet容器或EJB容器,它们都运行于支持Java的应用服务器中,因此tomcat/weblogic/websphere/jboss都算是应用服务器。


5. 了解Tomcat

tomcat是JDK+servlet(严格地说是+jsp)实现的精简版的java EE,由于它只在JDK的基础上附加了jsp和servlet类库,所以它的应用范围主要是web应用。

它是一种应用程序服务器,只提供servlet容器,同时还提供apache解析静态HTML,只不过之它的处理能力不如独立的apache服务器。


对于tomcat来说,它高度模块化,通过各个组件实现各种功能。它的体系结构如下图所示:

img

  • server是顶级类,一个server算是一个tomcat实例,在此层次中可定义tomcat服务的监听端口。
  • service是server下的子组件,用于封装绑定connector和container,并为它们提供一个名称属性。有了service就可以提供相关的服务,如监听TCP连接请求、处理http请求。注意server是管理整个tomcat实例的层次,它和提供服务没有关系。
  • connector是连接器,定义http协议(默认)以及该协议的监听端口。连接器用于接收客户端请求并将container处理的数据返回给客户端
  • container称为容器,它和connector连接器进行绑定。该容器内有4个子容器,包括:engine容器、host容器、context容器、Wrapper容器。容器用于分析、处理请求,并构建响应给connector以发送给客户端。它和connector是tomcat的心脏组件。
  • engine容器定义servlet引擎,用于定义引擎的名称、默认的虚拟主机。引擎用于分析http请求并将请求转发给对应的虚拟主机。
  • host容器用于定义虚拟主机。
  • context容器用于定义webapp,一个context定义一个webapp。它是真正管理servlet容器的层次。
  • wrapper容器对应的是真正的servlet容器,一个wrapper代表一个servlet,它负责管理一个Servlet,包括的Servlet的装载、初始化、执行以及资源回收。Wrapper是最底层的容器,一个context只能包含一个wrapper。在配置文件中,无法配置该容器的属性。
  • 还有一些其他组件,如session管理组件、JMX等。

一个server可以有多个service。一个service可以有多个connector和唯一的container。container是容器类,从container层次开始,真正进入servlet容器相关的过程。它包含了唯一的engine容器,engine容器中包含了一个或多个host容器,host容器中包含了一个或多个context容器,context容器中包含了唯一的wrapper。它们的组织结构大致如下:

<server>
    <service>
        <connector />
        <engine>
            <host>
                <context />
                <context />
            </host>
            <host>
                <context />
            </host>
        </engine>
    </service>

    <service>
         ......
    </service>
</server>

6. 部署JDK环境

下面通过二进制包进行部署,先创建软件包存放目录、软件运行目录、创建软链接方便升级。(JDK下载点这

#创建软件包存放目录、软件运行目录
[root@web01 ~]# mkdir -p /server/soft
[root@web01 ~]# mkdir -p /app/tools

#上传软件包到soft目录,进行解压到指定目录
[root@web01 ~]# cd /server/soft/
[root@web01 soft]# tar xf jdk-8u60-linux-x64.tar.gz -C /app/tools/

#创建软链接
[root@web01 soft]# ln -s /app/tools/jdk1.8.0_60/ /app/tools/jdk

#查看
[root@web01 soft]# ll /app/tools/
total 0
lrwxrwxrwx 1 root root  23 Mar 27 22:55 jdk -> /app/tools/jdk1.8.0_60/
drwxr-xr-x 8   10  143 255 Aug  4  2015 jdk1.8.0_60

配置JAVA环境变量,一般是二进制安装需要配置,yum安装不需要

cat >>/etc/profile<<'EOF'
export JAVA_HOME=/app/tools/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
EOF

Tips:'EOF'是对下面的$不进行解析!


使环境变量生效并检查Java版本

[root@web01 ~]# source /etc/profile
[root@web01 ~]# java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

7. 部署Tomcat环境

下面也是通过二进制包进行部署,先把Tomcat软件包上传,解压到指定目录。下载地址点这!

#Tomcat软件包上传并解压到指定目录
[root@web01 ~]# cd /server/soft/
[root@web01 soft]# tar xf apache-tomcat-9.0.52.tar.gz -C /app/tools/

#创建软链接
[root@web01 soft]# ln -s /app/tools/apache-tomcat-9.0.52/ /app/tools/tomcat

#查看
[root@web01 soft]# ll /app/tools/
total 0
drwxr-xr-x 9 root root 220 Mar 27 23:17 apache-tomcat-9.0.52
lrwxrwxrwx 1 root root  23 Mar 27 22:55 jdk -> /app/tools/jdk1.8.0_60/
drwxr-xr-x 8   10  143 255 Aug  4  2015 jdk1.8.0_60
lrwxrwxrwx 1 root root  32 Mar 27 23:17 tomcat -> /app/tools/apache-tomcat-9.0.52/

检查检查tomcat版本信息,执行命令有内容即是OK

[root@web01 soft]# /app/tools/tomcat/bin/version.sh
Using CATALINA_BASE:   /app/tools/tomcat
Using CATALINA_HOME:   /app/tools/tomcat
Using CATALINA_TMPDIR: /app/tools/tomcat/temp
Using JRE_HOME:        /app/tools/jdk
Using CLASSPATH:       /app/tools/tomcat/bin/bootstrap.jar:/app/tools/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Server version: Apache Tomcat/9.0.52
Server built:   Jul 31 2021 04:12:17 UTC
Server number:  9.0.52.0
OS Name:        Linux
OS Version:     3.10.0-1160.el7.x86_64
Architecture:   amd64
JVM Version:    1.8.0_60-b27
JVM Vendor:     Oracle Corporation

启动、关闭Tomcat

[root@web01 ~]# /app/tools/tomcat/bin/startup.sh
[root@web01 ~]# /app/tools/tomcat/bin/shutdown.sh

Tomcat不支持restart和reload!

image-20230328130950979


查看进程与端口信息

#进程信息
[root@web01 soft]# ps -ef | grep java
root      52035      1 16 01:07 pts/0    00:00:03 /app/tools/jdk/bin/java -Djava.util.logging.config.file=/app/tools/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /app/tools/tomcat/bin/bootstrap.jar:/app/tools/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/app/tools/tomcat -Dcatalina.home=/app/tools/tomcat -Djava.io.tmpdir=/app/tools/tomcat/temp org.apache.catalina.startup.Bootstrap start
root      52061   2061  0 01:08 pts/0    00:00:00 grep --color=auto java

#端口信息
[root@web01 soft]# ss -lntup | grep java
tcp    LISTEN     0      1        [::ffff:127.0.0.1]:8005               [::]:*                   users:(("java",pid=52035,fd=63))
tcp    LISTEN     0      100    [::]:8080               [::]:*                   users:(("java",pid=52035,fd=55))

8. 了解Tomcat目录

8.1 主目录

目录 作用
bin 该目录存放Tomcat管理命令,jvm配置
conf 该目录存放Tomcat配置文件,主要是server.xml
lib 该目录存放库文件,Tomcat所需要的依赖文件
logs 日志文件目录
temp 临时文件目录
webapps Tomcat站点目录
work 该目录存放Tomcat加载代码的时候临时文件

8.2 bin目录

文件 作用
startup.sh 启动Tomcat
shutdown.sh 关闭Tomcat
catalina.sh startup.sh或shutdown.sh都会调用这个主脚本
未来修改jvm选项/参数,配置最大内存或其他选项

8.3 conf目录

文件 作用
server.xml Tomcat主配置文件
tomcat-users.xml Tomcat管理端的配置文件
logging.properties 日志功能
web.xml Tomcat本身配置,web功能配置。

8.4 logs目录

目录或文件 作用
localhost_access_log.2023-03-28.txt Tomcat访问日志
catalina.out 应用日志(启动时间,错误信息,启动流程),这个文件不会清空。
catalina.2023-03-28.log 应用日志的切割日志,每天切割。

8.5 webapps目录

目录或文件 作用
ROOT 站点目录,war包自动解压,自动部署。

9. 部署应用

方案 部署java应用的方式 应用场景
1 Java代码放在tomcat站点目录下面(war包) 通用,需要准备tomcat
2 java代码生成jar包,通过java命令运行jar包(相当于集成tomcat功能) 更加方便,只需要准备好jdk就可以运行jar包

第1种方案就是把代码放到webapps下面,然后启动tomcat即可。
第2种方案 java -jar xxxx.jar


9.1 通过war包进行部署

将war包上传到tomcat目录下的webapps目录。

[root@web01 ~]# cd /app/tools/tomcat/webapps/
[root@web01 webapps]# ll
total 8
drwxr-x--- 15 root root 4096 Mar 27 23:17 docs
drwxr-x---  7 root root   99 Mar 27 23:17 examples
drwxr-x---  6 root root   79 Mar 27 23:17 host-manager
drwxr-x---  6 root root  114 Mar 27 23:17 manager
drwxr-x---  3 root root   41 Mar 28 02:44 memtest        #自动解压war包
-rw-r--r--  1 root root  643 Mar 28 02:44 memtest.war
drwxr-x---  3 root root  223 Mar 27 23:17 ROOT

访问测试,OK!

image-20230328144649359


9.2 通过jar包进行部署

将jar包上传或者从远程拉取到本地。

[root@web01 ~]# wget -O nginxWebUI.jar http://file.nginxwebui.cn/nginxWebUI-3.2.9.jar
--2023-03-28 02:49:01--  http://file.nginxwebui.cn/nginxWebUI-3.2.9.jar
Resolving file.nginxwebui.cn (file.nginxwebui.cn)... 222.186.52.86
Connecting to file.nginxwebui.cn (file.nginxwebui.cn)|222.186.52.86|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 39412890 (38M) [application/java-archive]
Saving to: ‘nginxWebUI.jar’

100%[======================================================>] 39,412,890   532KB/s   in 90s

2023-03-28 02:50:32 (428 KB/s) - ‘nginxWebUI.jar’ saved [39412890/39412890]

启动jar包

[root@web01 ~]# java -jar nginxWebUI.jar > /dev/null &
[1] 53293

访问测试,OK!

image-20230328150255022


10. Systemctl管理Tomcat

编辑配置文件/usr/lib/systemd/system/tomcat.service,修改/增加户都要systemctl daemon-reload 生效。


systemctl配置结构

[Unit]	指定注释信息,依赖(先后顺序)
Description	说明与注释
After	在这里指定的服务之后运行 network.target
[Service]	用于指定服务开启命令,关闭命令,重启命令
Type=notify	指定类型 simple或forking即可
ExecStart	服务启动命令
ExecStop	服务关闭命令
Reload	    重启命令
EnvironmentFile	配置环境变量的文件(一般对于编译安装,二进制安装需要加上)
[Install]	内容固定,用于指定运行级别
WantedBy=multi-user.target	运行级别

下面书写tomcat使用的systemctl配置文件

先创建一个变量文件/etc/sysconfig/tomcat,内容如下:

[root@web01 ~]# cat /etc/sysconfig/tomcat
JAVA_HOME=/app/tools/jdk
PATH=/app/tools/jdk/bin:/app/tools/jdk/jre/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar

编辑systemctl配置文件/usr/lib/systemd/system/tomcat.service

[root@web01 ~]# cat /usr/lib/systemd/system/tomcat.service
[Unit]
Description=java tomcat service
After=network.target

[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/tomcat
ExecStart=/app/tools/tomcat/bin/startup.sh
ExecStop=/app/tools/tomcat/bin/shutdown.sh
Reload=/app/tools/tomcat/bin/shutdown.sh && sleep 3 && /app/tools/tomcat/bin/startup.sh

[Install]
WantedBy=multi-user.target

重新加载systemd配置文件并使用tomcat

[root@web01 ~]# systemctl daemon-reload
[root@web01 ~]# ss -lntup | grep 8080

[root@web01 ~]# systemctl start tomcat
[root@web01 ~]# ss -lntup | grep 8080
tcp    LISTEN     0      100    [::]:8080               [::]:*                   users:(("java",pid=57916,fd=55))

[root@web01 ~]# systemctl stop tomcat
[root@web01 ~]# ss -lntup | grep 8080

11. Tomcat配置文件server.xml详解

<?xml version="1.0" encoding="UTF-8"?>
<!--
<Server>元素代表整个容器,是Tomcat实例的顶层元素,它包含一个<Service>元素,并且它不能做为任何元素的子元素。
port指定Tomcat监听shutdown命令端口,终止服务器运行时,必须在Tomcat服务器所在的机器上发出shutdown命令,该属性是必须的。
shutdown指定终止Tomcat服务器运行时,发给Tomcat服务器的shutdown监听端口的字符串,该属性必须设置。

不过基于安全角度的考虑,通常不允许远程进行。address="" 监听端口绑定的地址。如不指定,则默认为Localhost,即只能在localhost上发送SHUTDOWN命令;
-->
<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" />

    
<!--开启tomcat认证功能, 管理端认证-->
  <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就能提供服务了。service组件中封装connector和container,它同时也表示将此service中的connector和container绑定起来,即由它们组成一个service向外提供服务。 

此service的显示名称,该名称主要用于在日志中进行标识service。一般来说无关紧要,默认为Catalina。
-->
  <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:指定超时的时间数(以毫秒为单位)
-->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
      
<!--
engine,核心容器组件,catalina引擎,负责通过connector接收用户请求并处理请求,将请求转至对应的虚拟主机host。
defaultHost指定缺省的处理请求的主机名,它至少与其中的一个host元素的name属性值是一样的。
-->
    <Engine name="Catalina" defaultHost="localhost">
        
<!--Realm表示存放用户名,密码及role的数据库-->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

<!--
        Host表示一个虚拟主机
        name:指定主机名
        appBase:应用程序基本目录,即存放应用程序的目录.一般为appBase="webapps" ,也可以写绝对路径。
        unpackWARs:如果为true,则tomcat会自动将WAR文件解压,否则不解压,直接从WAR文件中运行应用程序
        autoDeploy:在tomcat启动时,是否自动部署加载到jvm。
        xmlValidation:是否启动xml的校验功能,一般xmlValidation="false"。
        xmlNamespaceAware:检测名称空间,一般xmlNamespaceAware="false"。
-->
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
          
          
<!--
配置日志信息
directory="logs"               指定tomcat访问日志目录
prefix="localhost_access_log"  访问日志文件名字的前部分
suffix=".txt"                  访问日志文件名字的后部分
pattern= "%h %l %u %t &quot;%r&quot; %s %b"   访问日志格式(&quot;表示双引号)
-->
        <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" />
<!-- 
%h 客户端ip地址
%t 时间
%r 请求起始行(方法 uri http)
%s 状态码
%b 资源大小
%{Referer}i 跳转
%{User-Agent}i 客户端
%{X-Forwarded-For}i 真实客户端ip
-->
      </Host>
    </Engine>
  </Service>
</Server>

Tips:其余详细配置可参考骏马金龙博主的文章,点这


12. Tomcat处理用户请求过程

<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
    
 <!-- 准备处理请求 -->
  <Connector port="8080" />   
    
 <!-- Engine 指定默认的站点 默认是www.yinjay.com -->
  <Engine name="Catalina" defaultHost="www.yinjay.com">
      
 <!-- 虚拟主机 -->
   <Host name="blog.yinjay.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
    <Valve 指定日志格式,名字>
   </Host>
       
  <!-- 虚拟主机 -->
   <Host name="www.yinjay.com">
    <Valve 指定日志格式,名字>
   </Host>
  </Engine>
</Service>
</Server>
  1. 用户访问tomcat配置上的端口。
  2. Connector连接器用于接收客户端发送的请求。
  3. Engine从Connector上接收请求,并将请求给对应的虚拟主机进行处理。
  4. Host容器从Connector接收到请求进行分析后,将相关的属性参数传递给对应的(筛选方式是从请求首部的host字段和虚拟主机名称进行匹配)虚拟host进行处理。如果没有合适的虚拟主机,则传递给默认虚拟主机。
  5. 虚拟主机处理完后,返回完整的响应数据给connector。
  6. 最后通过connector将响应数据返回给客户端。

13. 使用虚拟主机功能

域名 站点目录 日志
www.yinjay.com /app/tools/tomcat/www tomcat主目录的logs目录下
zrlog.yinjay.com /app/tools/tomcat/webapps tomcat主目录的logs目录下

修改tomcat主目录下的conf目录的server.xml配置文件

<?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" />


  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

    <Engine name="Catalina" defaultHost="zrlog.yinjay.com">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

        <Host name="www.yinjay.com"  appBase="www" unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve"
               directory="logs"
               prefix="www_access" suffix=".log"
               pattern="%h %l %u %t&quot;%r&quot; %s %b &quot;%{Referer}i&quot;&quot;%{User-Agent}i&quot; &quot;%{X-Forwarded-For}i&quot;" />
        </Host>

        <Host name="zrlog.yinjay.com"  appBase="webapps" unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve"
               directory="logs"
               prefix="zrlog_access" suffix=".log"
               pattern="%h %l %u %t&quot;%r&quot; %s %b &quot;%{Referer}i&quot;&quot;%{User-Agent}i&quot; &quot;%{X-Forwarded-For}i&quot;" />
        </Host>
    </Engine>
  </Service>
</Server>

Tips:没有定义任何context,将以appBase下的ROOT作为默认处理路径!

定义了path但没有定义docBase属性时,docBase将根据path推断出它的路径。例如添加下列Context,这路径为Host中的appBase路径 www/xuexi


重启Tomcat

systemctl restart tomcat

www目录创建测试文件

mkdir -p /app/tools/tomcat/www/ROOT
echo www tomcat > /app/tools/tomcat/www/ROOT/index.jsp

下面下载一个java博客war包,点这!。将war上传到/app/tools/tomcat/webapps目录下。

#上传war包到指定目录,已自动解压
[root@web01 ~]# cd /app/tools/tomcat/webapps/
[root@web01 webapps]# ll
total 10988
drwxr-x--- 15 root root     4096 Mar 27 23:17 docs
drwxr-x---  7 root root       99 Mar 27 23:17 examples
drwxr-x---  6 root root       79 Mar 27 23:17 host-manager
drwxr-x---  6 root root      114 Mar 27 23:17 manager
drwxr-x---  3 root root       41 Mar 28 02:44 memtest
-rw-r--r--  1 root root      643 Mar 28 02:44 memtest.war
drwxr-x---  3 root root      223 Mar 27 23:17 ROOT
drwxr-x---  9 root root      126 Mar 29 03:54 zrlog-2.2.1-efbe9f9-release
-rw-r--r--  1 root root 11243048 Mar 29 03:54 zrlog-2.2.1-efbe9f9-release.war
[root@web01 webapps]# mv zrlog-2.2.1-efbe9f9-release zrlog

#将zrlog目录中所有文件移至ROOT目录下
[root@web01 webapps]# rm -rf ROOT/*
[root@web01 webapps]# mv zrlog/* ROOT/

在MariaDB数据库上进行创建zrlog数据库和创建授权用户。

create database zrlog;
grant all on zrlog.* to 'zrlog'@'172.16.1.%' identified by 'Huawei@123';
flush privileges;

访问zrlog.yinjay.com:8080,进行安装!

image-20230329160112612


14. 配置多实例Tomcat

复制多份Tomcat并重新命名目录

[root@web01 ~]# cd /server/soft/
[root@web01 soft]# ll
total 188248
-rw-r--r-- 1 root root  11524133 Mar 27 23:16 apache-tomcat-9.0.52.tar.gz
-rw-r--r-- 1 root root 181238643 Mar 27 22:53 jdk-8u60-linux-x64.tar.gz
[root@web01 soft]# tar xf apache-tomcat-9.0.52.tar.gz

[root@web01 soft]# cp -r apache-tomcat-9.0.52 /app/tools/tomcat-8081
[root@web01 soft]# cp -r apache-tomcat-9.0.52 /app/tools/tomcat-8082

修改配置文件(端口信息)

[root@web01 soft]# sed -i "s#8080#8081#g" /app/tools/tomcat-8081/conf/server.xml
[root@web01 soft]# sed -i "s#8005#8006#g" /app/tools/tomcat-8081/conf/server.xml
[root@web01 soft]# sed -i "s#8080#8082#g" /app/tools/tomcat-8082/conf/server.xml
[root@web01 soft]# sed -i "s#8005#8007#g" /app/tools/tomcat-8082/conf/server.xml

书写Tomcat的systemctl配置文件,先查看现有的配置

[root@web01 soft]# cat /usr/lib/systemd/system/tomcat.service
[Unit]
Description=java tomcat service
After=network.target

[Service]
Type=forking
EnvironmentFile=/etc/sysconfig/tomcat
ExecStart=/app/tools/tomcat/bin/startup.sh
ExecStop=/app/tools/tomcat/bin/shutdown.sh
Reload=/app/tools/tomcat/bin/shutdown.sh && sleep 3 && /app/tools/tomcat/bin/startup.sh

[Install]
WantedBy=multi-user.target

复制现有的配置进行修改

[root@web01 ~]# cd /usr/lib/systemd/system/
[root@web01 system]# cp tomcat.service tomcat-8081.service
[root@web01 system]# cp tomcat.service tomcat-8082.service
[root@web01 system]# sed -i 's#/tomcat/#/tomcat-8081/#g' tomcat-8081.service
[root@web01 system]# sed -i 's#/tomcat/#/tomcat-8082/#g' tomcat-8082.service

重新加载systemd配置文件

[root@web01 ~]# systemctl daemon-reload

创建测试文件

[root@web01 ~]# echo tomcat 8081 > /app/tools/tomcat-8081/webapps/ROOT/index.jsp
[root@web01 ~]# echo tomcat 8082 > /app/tools/tomcat-8082/webapps/ROOT/index.jsp

启动服务并访问测试

[root@web01 ~]# systemctl start tomcat-8081
[root@web01 ~]# systemctl start tomcat-8082

#检查端口情况
[root@web01 ~]# ss -lntup | grep java
tcp    LISTEN     0      1        [::ffff:127.0.0.1]:8005               [::]:*                   users:(("java",pid=89689,fd=64))
tcp    LISTEN     0      1        [::ffff:127.0.0.1]:8006               [::]:*                   users:(("java",pid=103960,fd=63))
tcp    LISTEN     0      1        [::ffff:127.0.0.1]:8007               [::]:*                   users:(("java",pid=103992,fd=63))
tcp    LISTEN     0      50       [::ffff:127.0.0.1]:41513              [::]:*                   users:(("java",pid=89713,fd=19))
tcp    LISTEN     0      50       [::ffff:127.0.0.1]:21513              [::]:*                   users:(("java",pid=89713,fd=14))
tcp    LISTEN     0      100    [::]:8080               [::]:*                   users:(("java",pid=89689,fd=55))
tcp    LISTEN     0      100    [::]:8081               [::]:*                   users:(("java",pid=103960,fd=55))
tcp    LISTEN     0      100    [::]:8082               [::]:*                   users:(("java",pid=103992,fd=55))
tcp    LISTEN     0      50       [::ffff:127.0.0.1]:51513              [::]:*                   users:(("java",pid=89713,fd=13))

浏览器访问测试,OK!

image-20230329201353855


15. 动静分离

环境准备 说明
web01 nginx(处理静态)、tomcat(处理动态)
db01 存储数据信息
nfs01 暂且忽略,理应把用户上传的内容挂载到存储上

Tips:web01安装nginx、tomcat,db01安装mariadb数据库,参考之前的命令!


通过部署zrlog博客来实现动静分离,首先在web01上安装nginx、tomcat并书写好systemctl配置文件。下面下载一个java博客war包,点这!。将war上传到/app/tools/tomcat/webapps目录下。

#上传war包到指定目录,已自动解压
[root@web01 ~]# cd /app/tools/tomcat/webapps/
[root@web01 webapps]# ll
total 10988
drwxr-x--- 15 root root     4096 Mar 27 23:17 docs
drwxr-x---  7 root root       99 Mar 27 23:17 examples
drwxr-x---  6 root root       79 Mar 27 23:17 host-manager
drwxr-x---  6 root root      114 Mar 27 23:17 manager
drwxr-x---  3 root root       41 Mar 28 02:44 memtest
-rw-r--r--  1 root root      643 Mar 28 02:44 memtest.war
drwxr-x---  2 root root        6 Mar 29 09:18 ROOT
drwxr-x---  9 root root      126 Mar 29 03:56 zrlog-2.2.1-efbe9f9-release
-rw-r--r--  1 root root 11243048 Mar 29 03:54 zrlog-2.2.1-efbe9f9-release.war

#复制所有代码文件到ROOT目录下
[root@web01 webapps]# cp -r zrlog-2.2.1-efbe9f9-release/* ROOT/

#创建nginx目录
[root@web01 ~]# mkdir -p /app/code/zrlog/static

#复制所有代码文件到nginx目录下
[root@web01 ~]# cp -r /app/tools/tomcat/webapps/zrlog-2.2.1-efbe9f9-release/* /app/code/zrlog/static/

#赋予权限
[root@web01 ~]# chown -R nginx.nginx /app/code/zrlog/static/

#为什么这么做呢,因为动态代码和静态代码没有做分离,同时在nginx配置文件中root直接指tomcat的webapps/ROOT目录会直接报403错误!所以在部署这样子的项目,前期构建项目时就要进行做动静分离代码。

修改Server.xml配置文件

[root@web01 tomcat]# pwd
/app/tools/tomcat
[root@web01 tomcat]# cat conf/server.xml
<?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" />


  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

    <Engine name="Catalina" defaultHost="zrlog.yinjay.com">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

        <Host name="zrlog.yinjay.com"  appBase="webapps" unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve"
               directory="logs"
               prefix="zrlog_access" suffix=".log"
               pattern="%h %l %u %t&quot;%r&quot; %s %b &quot;%{Referer}i&quot;&quot;%{User-Agent}i&quot; &quot;%{X-Forwarded-For}i&quot;" />
        </Host>
    </Engine>
  </Service>
</Server>

启动tomcat服务

systemctl start tomcat

在MariaDB数据库上进行创建zrlog数据库和创建授权用户。

create database zrlog;
grant all on zrlog.* to 'zrlog'@'172.16.1.%' identified by 'Huawei@123';
flush privileges;

书写nginx的配置文件

[root@web01 ~]# cat /etc/nginx/conf.d/zrlog.yinjay.com.conf
server {
    listen 80;
    server_name zrlog.yinjay.com;

    location / {
        proxy_pass http://10.0.0.7:8080;
        proxy_set_header Host $http_host;
    }

    location ~* \.(html|css|js|png|jpg|jpeg)$ {
        root /app/code/zrlog/static/;
        expires 30d;
    }

}

Tisp:记得在/etc/nginx/nginx.conf把server区块注释!


启动nginx服务

systemctl start nginx

宿主机进行访问zrlog.yinjay.com测试,测试看出已经动静分离进行处理。

下面是查看nginx的访问日志

image-20230331191015123


下面是查看tomcat的访问日志

image-20230331191219864


16. 监控Tomcat

通过命令获取java进程信息,jvm信息。

java管理的命令
java命令 用于启动代码,启动jar包或tomcat启动war,背后都会用java命令。
jps java ps命令,查看显示java进程。
jstack java进程和线程信息,运行状态等等。
jmap 查看jvm内存使用情况,导出jvm内存(用于故障分析)。

16.1 jps查看当前机器上已装载的jvm

[root@web01 ~]# jps -lvm

image-20230331210818777


16.2 jstack查看java进程与线程信息

jstack命令主要用来查看Java线程的调用堆栈的,可以用来分析线程问题(如死锁)。

用法:jstack java进程的pid(可通过jps -lvm获取,下面就取上面已经得出来的pid)

[root@web01 ~]# jstack 112379
2023-03-31 08:56:49
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.60-b23 mixed mode):

-----------(忽略大部分输出)------------
#更多的是关注下面的线程状态
"main" #1 prio=5 os_prio=0 tid=0x00007f4dd8009000 nid=0x1b6fe runnable [0x00007f4de1d8c000]
   java.lang.Thread.State: RUNNABLE #也就是这里
        at java.net.PlainSocketImpl.socketAccept(Native Method)
        at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
        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:602)
        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:497)
        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=0x00007f4dd806d800 nid=0x1b6ff runnable

"VM Periodic Task Thread" os_prio=0 tid=0x00007f4dd80b9000 nid=0x1b706 waiting on condition

JNI global references: 453

通常流程先查出最耗费CPU的线程

top -Hp 进程pid
[root@web01 ~]# top -Hp 112379

比如下面这条线程最耗费CPU

image-20230331210921505


先将线程pid进行转换成十六进制

[root@web01 ~]# printf "%x\n" 112429
1b72d

先将信息输出到文件,然后通过上面转换的十六进制信息进行查找。

[root@web01 ~]# jstack 112379 > info.txt

在文件中进行定位到指定位置,就能看到该线程的状态。

image-20230331211136560


值得关注的线程状态有:

死锁:Deadlock(重点关注)
② 执行中:Runnable
等待资源:Waiting on condition(重点关注)
等待获取监视器:Waiting on monitor entry(重点关注)
⑤ 暂停:Suspended
⑥ 对象等待中:Object.wait() 或 TIMED_WAITING
⑦ 阻塞:Blocked(重点关注)
⑧ 停止:Parked


16.3 jmap查看Jvm内存使用情况

jmap命令可以获得运行中的jvm的堆的快照,从而可以离线分析堆,以检查内存泄漏,检查一些严重影响性能的大对象的创建,检查系统中什么对象最多,各种对象所占内存的大小等等。

用法:jmap -heap java进程的pid

[root@web01 ~]# jmap -heap 112379
Attaching to process ID 112379, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.60-b23

using thread-local object allocation.
Mark Sweep Compact GC

Heap Configuration:
   MinHeapFreeRatio         = 40
   MaxHeapFreeRatio         = 70
   MaxHeapSize              = 478150656 (456.0MB)
   NewSize                  = 10485760 (10.0MB)
   MaxNewSize               = 159383552 (152.0MB)
   OldSize                  = 20971520 (20.0MB)
   NewRatio                 = 2
   SurvivorRatio            = 8
   MetaspaceSize            = 21807104 (20.796875MB)
   CompressedClassSpaceSize = 1073741824 (1024.0MB)
   MaxMetaspaceSize         = 17592186044415 MB
   G1HeapRegionSize         = 0 (0.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 12451840 (11.875MB)
   used     = 3106144 (2.962249755859375MB)
   free     = 9345696 (8.912750244140625MB)
   24.945261101973685% used
Eden Space:
   capacity = 11075584 (10.5625MB)
   used     = 2096104 (1.9990005493164062MB)
   free     = 8979480 (8.563499450683594MB)
   18.925448987610945% used
From Space:
   capacity = 1376256 (1.3125MB)
   used     = 1010040 (0.9632492065429688MB)
   free     = 366216 (0.34925079345703125MB)
   73.39041573660714% used
To Space:
   capacity = 1376256 (1.3125MB)
   used     = 0 (0.0MB)
   free     = 1376256 (1.3125MB)
   0.0% used
tenured generation:
   capacity = 27480064 (26.20703125MB)
   used     = 16588880 (15.820388793945312MB)
   free     = 10891184 (10.386642456054688MB)
   60.366962755254136% used

20025 interned Strings occupying 2180064 bytes.

生成内存dump文件,未来通过专用的jvm内存分析工具,打开分析这个文件即可。

用法:jmap -dump:file=文件名.hprof, format=b java进程pid

[root@web01 ~]# jmap -dump:file=/root/test.hprof,format=b 112379
Dumping heap to /root/test.hprof ...
Heap dump file created

16.4 开启java远程监控功能

来通过各种监控工具(Zabbix/Grafana/Promethues/...),监控Tomcat/java,或者用于开发调试代码与查看Java状态。


开启流程:

  • 修改java配置(tomcat配置的catalina.sh)
  • 重启java(tomcat)
  • 监控(可从监控插件或者window下启动java工具查看)

修改tomcat/bin目录下的catalina.sh,添加下列内容。CATALINA_OPTS就是java变量修改tomcat启动的时候参数,本质就是给java命令增加些参数。

CATALINA_OPTS="$CATALINA_OPTS \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=12345 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname=10.0.0.7"

jmxremote选项说明
Dcom.sun.management.jmxremote 开启远程监控功能
Dcom.sun.management.jmxremote.port=12345 指定功能的端口号:12345
Dcom.sun.management.jmxremote.authenticate=false 是否开启认证功能,关闭
Dcom.sun.management.jmxremote.ssl=false 是否开启ssl证书,关闭
Djava.rmi.server.hostname=10.0.0.7 指定本机的内网或公网ip

重启tomcat服务,然后查看端口情况

image-20230401093942207


jps -lvm查看,已经加载

image-20230401094044210


在宿主机通过jvisualvm工具进行监控(模拟zabbix监控java)

image-20230401094302747


16.5 高负载排查过程

排障流程 具体命令和方法
通过监控得知系统负载高,登录这台机器进行初步分析原因 通过监控或告警
分析cpu导致还是磁盘io导致 top命令关注下面情况
us、sy数值高为CPU导致
wa数值高为IO导致
查出对应进程出现异常(此处指java导致时) CPU导致可在top信息中看CPU利用率高的对应进程PID
IO导致可以用iotop -P命令看最高IO读写的进程PID
查看jvm内存情况,导出jvm内存进行分析 内存情况: jmap -heap java的PID
导出jvm内存:dump:file=xxx.hprof,format=b java的PID
分析jvm内存,需要开发参与 通过内存分析工具:Memory Analyzer Tool
分析应用日志 catalina.out
分析网站日志 xxxx.log
看日志是否有异常
找出原因 解决与处理

17. Session会话共享保持

环境 说明 ip
lb01 nginx实现负载均衡 10.0.0.5、172.16.1.5
web01 web服务,tomcat 172.16.1.7
web02 web服务,tomcat 172.16.1.8
db01 数据库、redis 172.16.1.51

Tips:本实验使用不到数据库,只是在数据库的机器上部署redis!


17.1 下载插件并修改配置文件

tomcat-cluster-redis-session插件下载地址:https://github.com/ran-jit/tomcat-cluster-redis-session-manager/ 选择适合的版本下载后上传到tomcat主机上(web01、web02)


以下步骤web01、web02都进行相同的修改。

[root@web01 ~]# cd /server/soft/
[root@web01 soft]# ll
total 189148
drwxr-xr-x 9 root root       220 Mar 29 07:57 apache-tomcat-9.0.52
-rw-r--r-- 1 root root  11524133 Mar 27 23:16 apache-tomcat-9.0.52.tar.gz
-rw-r--r-- 1 root root 181238643 Mar 27 22:53 jdk-8u60-linux-x64.tar.gz
drwxr-xr-x 3 root root        96 Mar 31 23:17 __MACOSX
drwxr-xr-x 4 root root        64 Aug 12  2019 tomcat-cluster-redis-session-manager
-rw-r--r-- 1 root root    921429 Mar 31 23:16 tomcat-cluster-redis-session-manager.zip

[root@web01 soft]# tree tomcat-cluster-redis-session-manager
tomcat-cluster-redis-session-manager
├── conf
│   └── redis-data-cache.properties   #连接redis的配置文件
├── lib                               #依赖,tomcat-redis-session管理插件
│   ├── commons-pool2-2.6.2.jar
│   ├── jedis-3.0.1.jar
│   ├── slf4j-api-1.7.26.jar
│   └── tomcat-cluster-redis-session-manager-4.0.jar
└── readMe.txt

2 directories, 6 files

复制jar包到tomcat的lib目录中,复制配置文件到tomcat的conf目录中。

[root@web01 soft]# cp tomcat-cluster-redis-session-manager/lib/*.jar /app/tools/tomcat/lib/
[root@web01 soft]# cp tomcat-cluster-redis-session-manager/conf/redis-data-cache.properties /app/tools/tomcat/conf/

修改配置文件

[root@web01 ~]# vim /app/tools/tomcat/conf/redis-data-cache.properties
redis.hosts=172.16.1.51:6379

[root@web01 ~]# vim /app/tools/tomcat/conf/context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    
    #在Context里面增添下列两行
    <Valve className="tomcat.request.session.redis.SessionHandlerValve" />
    <Manager className="tomcat.request.session.redis.SessionManager" />
</Context>

17.2 安装redis并修改配置

db01下进行

yum install -y redis

更改redis服务监听地址

[root@db01 ~]# grep -n '^bind' /etc/redis.conf
61:bind 127.0.0.1
[root@db01 ~]# sed -i '61s/127.0.0.1/172.16.1.51/' /etc/redis.conf
[root@db01 ~]# grep -n '^bind' /etc/redis.conf
61:bind 172.16.1.51

启动redis服务并设置开机自启

[root@db01 ~]# systemctl start redis
[root@db01 ~]# systemctl enable redis
Created symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /usr/lib/systemd/system/redis.service.

检查服务状态

[root@db01 ~]# ps -ef |grep redis
redis     75726      1  0 23:43 ?        00:00:00 /usr/bin/redis-server 172.16.1.51:6379
root      75730  74049  0 23:43 pts/2    00:00:00 grep --color=auto redis

查询redis中的数据,目前为空

[root@db01 ~]# redis-cli -h 172.16.1.51
172.16.1.51:6379> keys *
(empty list or set)
172.16.1.51:6379>

17.3 书写测试文件并重启服务访问

web01书写测试文件

[root@web01 ~]# cat /app/tools/tomcat/webapps/ROOT/session.jsp
<body>
<%
System.out.println(session.getCreationTime());
out.println("<br> web01.yinjay.com SESSIONID:" + session.getId() + "<br>");
out.println("Session created  time is :" + session.getCreationTime()+ "<br>");
%>
</body>

web02书写测试文件

[root@web02 ~]# cat /app/tools/tomcat/webapps/ROOT/session.jsp
<body>
<%
System.out.println(session.getCreationTime());
out.println("<br> web02.yinjay.com SESSIONID:" + session.getId() + "<br>");
out.println("Session created  time is :" + session.getCreationTime()+ "<br>");
%>
</body>

web01、web02重启服务

systemctl restart tomcat

进行单独访问测试,redis查询到各自的session。

image-20230401115230190


17.4 接入负载均衡

在lb01上进行修改配置文件并重新加载配置。

[root@lb01 ~]# cat /etc/nginx/conf.d/lb01.conf
upstream tomcat_pools {
   server 172.16.1.7:8080;
   server 172.16.1.8:8080;

}

server {
   listen 80;
   server_name tomcat.yinjay.com;

   location / {
       proxy_pass http://tomcat_pools;
       proxy_set_header X-Forwarded-For $remote_addr;
       proxy_set_header Host $http_host;
   }

}

[root@lb01 ~]# systemctl reload nginx

在宿主机添加host记录10.0.0.5 tomcat.yinjay.com后并进行浏览器访问。第一次负载到web01,第二次负载到web02,然后进行查询redis都是同一个session,实现会话共享保持!

image-20230401120412053

image-20230401120432506


18. Maven代码编译

18.1 基本流程

大致流程:开发人员 ---> 代码仓库 ---> 拉取代码 ---> 代码通过maven进行编译 ---> maven根据代码配置pom.xml下载代码的依赖jar包 ---> 生成war包或jar包


18.2 配置maven环境

下载maven

[root@web01 ~]# cd /server/soft/
[root@web01 soft]# wget https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz

解压、建立软链接并检查可用

#解压
[root@web01 soft]# tar xf apache-maven-3.6.3-bin.tar.gz

#复制到其他目录
[root@web01 soft]# cp -r apache-maven-3.6.3 /app/tools/

#建立软链接
[root@web01 soft]# ln -s /app/tools/apache-maven-3.6.3/ /app/tools/maven

#通过输出版本信息检查可用
[root@web01 soft]# /app/tools/maven/bin/mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /app/tools/maven
Java version: 1.8.0_60, vendor: Oracle Corporation, runtime: /app/tools/jdk1.8.0_60/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-1160.el7.x86_64", arch: "amd64", family: "unix"

Tips:Maven前提也是需要依赖JDK!


配置maven环境,修改PATH环境变量。

#配置环境变量
[root@web01 ~]# echo 'export PATH=/app/tools/maven/bin/:$PATH' >> /etc/profile
[root@web01 ~]# source /etc/profile

#检查环境变量生效
[root@web01 ~]# mvn --version
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /app/tools/maven
Java version: 1.8.0_60, vendor: Oracle Corporation, runtime: /app/tools/jdk1.8.0_60/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.10.0-1160.el7.x86_64", arch: "amd64", family: "unix"

18.3 配置maven依赖下载源

在配置文件中找到下列内容,将不同的地方进行替换即可。

[root@web01 ~]# vim /app/tools/maven/conf/settings.xml
  <mirrors>
    <mirror>
      <id>aliyun maven</id>
      <mirrorOf>*</mirrorOf>
      <name>aliyun的maven公共仓库</name>
      <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
  </mirrors>

18.4 使用maven编译代码

18.4.1 编译jar包

下载nginxwebui项目代码

[root@web01 ~]# mkdir -p /app/tools/code
[root@web01 ~]# cd /app/tools/code/
[root@web01 code]# git clone https://gitee.com/cym1102/nginxWebUI.git
[root@web01 code]# ll
total 0
drwxr-xr-x 4 root root 217 Apr  1 03:20 nginxWebUI

修改项目代码的运行端口

[root@web01 code]# head -n 2 nginxWebUI/src/main/resources/app.yml
server:
  port: 9898

进行编译代码

#mvn clean package依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7个阶段。
[root@web01 code]# cd nginxWebUI
[root@web01 nginxWebUI]# mvn clean package

image-20230401153907489


运行jar包并进行访问测试

[root@web01 nginxWebUI]# java -jar target/nginxWebUI-3.4.8.jar > /dev/null &
[1] 18843
[root@web01 nginxWebUI]# ss -lntup | grep 9898
tcp    LISTEN     0      128    [::]:9898               [::]:*                   users:(("java",pid=18843,fd=24))

image-20230401154056058


18.4.2 编译war包

先安装npm,编译过程中需要用到

[root@web01 ~]# yum install npm -y

下载zrlog项目代码

[root@web01 ~]# cd /app/tools/code/
[root@web01 code]# git clone https://gitee.com/94fzb/zrlog.git

进行编译代码

[root@web01 code]# cd zrlog/
[root@web01 zrlog]# mvn clean package

image-20230401163301853

Tips:maven命令作用解释,点这!


19. Tomcat优化

19.1 安全优化

19.1.1 telnet管理端口保护
  • 修改tomcat shutdown端口
  • 修改shutdown关闭语句
#修改前
<Server port="8080" shutdown="SHUTDOWN">

#修改后
<Server port="8555" shutdown="yinjayshutdown">

Tips:在Tomcat的conf目录的server.xml配置文件!


19.1.2 ajp连接端口保护

ajp是用于tomcat与apache连接的时候接口,端口号是8009。

#从8.5版本开始就已经被注释了
 <!-- Define an AJP 1.3 Connector on port 8009 -->
    <!--
    <Connector protocol="AJP/1.3"
               address="::1"
               port="8009"
               redirectPort="8443" />
    -->

Tips:在Tomcat的conf目录的server.xml配置文件!


19.1.3 降权启动

让服务通过普通用户运行,降低维护服务的权限。正常是需要root权限的,现在仅需普通用户即可。

#添加普通用户
useradd tomcat

#修改systemd配置文件
/usr/lib/systemd/system/tomcat.service  里面的[Service]区块添加 User=tomcat

#重新加载配置文件
systemctl daemon-reload

#修改tomcat目录的所有者
chown -R tomcat.tomcat /app/tools/tomcat/

#修改sudo权限,让普通用户能够运行systemctl命令(默认已经拥有查看服务状态的权限)
visudo命令
tomcat  ALL=(ALL)       NOPASSWD: /bin/systemctl start tomcat,/bin/systemctl restart tomcat,/bin/systemctl stop tomcat

[root@web02 tomcat]# visudo -c #检查配置是否正确
/etc/sudoers: parsed OK

#切换到tomcat用户下,以下命令就可以使用了
sudo systemctl start tomcat
sudo systemctl restart tomcat
sudo systemctl stop tomcat

Tips:tomcat的降权启动容易,因为是直接都在一个目录,且使用端口非特权端口(普通用户可使用的)。nginx降权启动繁琐,因为使用到80和443端口,属于特权端口。目录和文件也都分散在个目录中,不好做降权!


19.1.4 文件列表访问控制

默认已经是关闭

        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>

Tips:在Tomcat的conf目录的web.xml配置文件!


19.1.5 Server header重写

将经过tomcat处理的数据包,修改响应头的内容。tomcat版本信息伪装成nginx、tengine等等。


19.2 性能优化

19.2.1 禁用DNS逆向解析功能
    <Connector port="8080" protocol="HTTP/1.1"
               enableLookups="false"  #加上这一条
               Server="Tengine"
               connectionTimeout="20000"
               redirectPort="8443" />

Tips:在Tomcat的conf目录的server.xml配置文件!


19.2.2 开启压缩功能

对应静态资源进行压缩,节省带宽。

<Connector port="8080" protocol="HTTP/1.1"
               enableLookups="false"
               Server="Tengine"
               compression="on"
               compressionMinSize="1024"
compressableMimeType="text/html,text/plain,text/css,application/javascript,application/json,application/x-font-ttf,application/x-font-otf"
               connectionTimeout="20000"
               redirectPort="8443" />

image-20230402112942650

Tips:在Tomcat的conf目录的server.xml配置文件!


Tips:本篇部分内容参考骏马金龙博主,感谢提供干货知识!

posted @ 2023-09-12 22:20  YinJayChen  阅读(36)  评论(0编辑  收藏  举报