目录

Tomcat介绍

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用

Tomcat 具有处理HTML静态资源页面的功能,它还是一个Servlet和JSP容器



一、centos7 基础环境

#修改主机名
[root@c7-tomcat-master-51 ~]# hostnamectl set-hostname c7-ca-200

#修改固定IP
[root@c7-tomcat-master-51 ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33 
TYPE="Ethernet"
BOOTPROTO="none"
IPADDR=172.29.7.51
PREFIX=24
GATEWAY=172.29.7.254
DNS1=114.114.114.114
NAME="ens33"
DEVICE="ens33"
ONBOOT="yes"

#重启网卡
[root@c7-tomcat-master-51 ~]# nmcli connection reload ;nmcli connection up ens33 
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/6)

#修改selinux为警告状态
[root@c7-tomcat-master-51 ~]# cat /etc/selinux/config 

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
#Disabled :不启用控制系统。
#permissive:开启控制系统,但是处于警告模式。即使你违反了策略的话它让你继续操作,但是把你的违反的内容记录下来。
#Enforcing:开启控制系统,处于强制状态。一旦违反了策略,就无法继续操作下去。
SELINUX=permissive
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted 

#动态修改selinux为警告状态
[root@c7-tomcat-master-51 ~]# setenforce 0

#永久停止防火墙
[root@c7-tomcat-master-51 ~]# systemctl disable --now firewalld
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.

#修改时区
[root@c7-tomcat-master-51 ~]# timedatectl set-timezone Asia/Shanghai

#时间同步
[root@c7-tomcat-master-51 ~]# cat /etc/chrony.conf 
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
#修改为阿里云时间服务器
server ntp1.alliyun.com iburst
#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst

....

#重启、开机自启、查看是否生效
[root@c7-tomcat-master-51 ~]# systemctl restart chronyd
[root@c7-tomcat-master-51 ~]# systemctl enable --now chronyd
[root@c7-tomcat-master-51 ~]# chronyc -n sources
210 Number of sources = 1
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^? 173.255.248.194               0   7     0     -     +0ns[   +0ns] +/-    0ns


二、Java安装

1、yum源安装

#查看以java开头的所有可用版本
[root@c7-tomcat-master-51 ~]# yum list java* --showduplicates
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: mirrors.bupt.edu.cn
 * extras: mirrors.bfsu.edu.cn
 * updates: mirrors.bfsu.edu.cn
Installed Packages
java-1.7.0-openjdk.x86_64                                                           1:1.7.0.261-2.6.22.2.el7_8                                              @anaconda
java-1.7.0-openjdk-headless.x86_64                                                  1:1.7.0.261-2.6.22.2.el7_8                                              @anaconda
java-1.8.0-openjdk.x86_64                                                           1:1.8.0.262.b10-1.el7                                                   @anaconda
java-1.8.0-openjdk-headless.x86_64                                                  1:1.8.0.262.b10-1.el7                                                   @anaconda

.....

#安装tomcat
[root@c7-tomcat-master-51 ~]# yum -y install java-1.8.0-openjdk java-1.8.0-openjdk-headless

#查看tomcat版本
[root@c7-tomcat-master-51 ~]# java -version
openjdk version "1.8.0_402"
OpenJDK Runtime Environment (build 1.8.0_402-b06)
OpenJDK 64-Bit Server VM (build 25.402-b06, mixed mode)

1.java hello world test

编译一个hello world的java程序

[root@c7-tomcat-master-51 ~]# yum -y install java-1.8.0-openjdk-devel

[root@c7-tomcat-master-51 ~]# cat hello_world.java 
class Hello{
    public static void main(String[] args)
    {
        System.out.println("hello,world");
    }
}

[root@c7-tomcat-master-51 ~]# javac hello_world.java 
[root@c7-tomcat-master-51 ~]# ll
-rw-r--r--. 1 root root  421 Feb 14 09:31 Hello.class
-rw-r--r--. 1 root root   98 Feb 14 09:30 hello_world.java

[root@c7-tomcat-master-51 ~]# java Hello
hello,world

2、rpm安装

#去官网找自己需要的版本,现在oracle那个官网不知道怎么回事不让直接使用wget下载了
https://www.oracle.com/cn/java/technologies/javase/javase8u211-later-archive-downloads.html

#下载完成后通过工具传上去,我这里用的xftp
[root@c7-tomcat-master-51 ~]# ls jdk-8u391-linux-x64.rpm -lh
-rw-r--r--. 1 root root 138M Feb 14 09:46 jdk-8u391-linux-x64.rpm

#可以用yum也可以用rpm,yum的好处就是如果存在依赖程序会自动下载
[root@c7-tomcat-master-51 ~]# yum -y install jdk-8u391-linux-x64.rpm 

[root@c7-tomcat-master-51 ~]# java -version
java version "1.8.0_391"
Java(TM) SE Runtime Environment (build 1.8.0_391-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.391-b13, mixed mode)

#配置java所需的环境
[root@c7-tomcat-master-51 ~]# cat /etc/profile.d/jdk.sh 
export JAVA_HOME=/usr/java/default
export PATH=$JAVA_HOME/bin:$PATH

#source和 . 都可以,就是为了执行一下
[root@c7-tomcat-master-51 ~]# . /etc/profile.d/jdk.sh

#目前的环境
[root@c7-tomcat-master-51 ~]# echo $PATH
/usr/java/default/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

#java的路径
[root@c7-tomcat-master-51 ~]# which java
/usr/java/default/bin/java

#文件目录在 /usr/java 下
[root@c7-tomcat-master-51 ~]# ls /usr/java/
default  jdk1.8.0-x64  latest

3、二进制安装

#官网网址
https://www.oracle.com/cn/java/technologies/javase/javase8u211-later-archive-downloads.html

#解压、切换目录、设置软链接,也可以mv修改目录名,但是不推荐
[root@c7-tomcat-master-51 ~]# tar xf jdk-8u391-linux-x64.tar.gz -C /usr/local/
[root@c7-tomcat-master-51 ~]# cd /usr/local/
[root@c7-tomcat-master-51 local]# ln -s jdk1.8.0_391/ jdk

[root@c7-tomcat-master-51 local]# cat /etc/profile.d/jdk.sh 
export JAVA_HOME=/usr/local/jdk
export PATH=$PATH:$JAVA_HOME/bin

[root@c7-tomcat-master-51 local]# . /etc/profile.d/jdk.sh 

[root@c7-tomcat-master-51 local]# java -version
openjdk version "1.8.0_262"
OpenJDK Runtime Environment (build 1.8.0_262-b10)
OpenJDK 64-Bit Server VM (build 25.262-b10, mixed mode)


三、Tomcat安装

1、yum源安装

[root@c7-tomcat-master-51 local]# yum list tomcat* --showduplicates
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: mirrors.bupt.edu.cn
 * extras: mirrors.bfsu.edu.cn
 * updates: mirrors.bfsu.edu.cn
Available Packages
tomcat.noarch                                                                         7.0.76-15.el7                                                           base   
tomcat.noarch                                                                         7.0.76-16.el7_9                                                         updates
tomcat-admin-webapps.noarch                                                           7.0.76-15.el7                                                           base   
tomcat-admin-webapps.noarch                                                           7.0.76-16.el7_9                                                         updates
tomcat-docs-webapp.noarch                                                             7.0.76-15.el7                                                           base   
tomcat-docs-webapp.noarch                                                             7.0.76-16.el7_9                                                         updates
tomcat-el-2.2-api.noarch                                                              7.0.76-15.el7                                                           base   
tomcat-el-2.2-api.noarch                                                              7.0.76-16.el7_9                                                         updates
....

[root@c7-tomcat-master-51 ~]# yum -y install tomcat tomcat-webapps tomcat-admin-webapps tomcat-docs-webapp

[root@c7-tomcat-master-51 ~]# systemctl enable --now tomcat
Created symlink from /etc/systemd/system/multi-user.target.wants/tomcat.service to /usr/lib/systemd/system/tomcat.service.

[root@c7-tomcat-master-51 ~]# ps -aux | grep tomcat
avahi       694  0.0  0.0  62268  2264 ?        Ss   10:08   0:00 avahi-daemon: running [c7-tomcat-master-51.local]
tomcat     2449 28.6  7.3 4570840 282204 ?      Ssl  10:28   0:11 /usr/lib/jvm/jre/bin/java -Djavax.sql.DataSource.Factory=org.apache.commons.dbcp.BasicDataSourceFactory -classpath /usr/share/tomcat/bin/bootstrap.jar:/usr/share/tomcat/bin/tomcat-juli.jar:/usr/share/java/commons-daemon.jar -Dcatalina.base=/usr/share/tomcat -Dcatalina.home=/usr/share/tomcat -Djava.endorsed.dirs= -Djava.io.tmpdir=/var/cache/tomcat/temp -Djava.util.logging.config.file=/usr/share/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager org.apache.catalina.startup.Bootstrap start
root       2525  0.0  0.0 112812   968 pts/0    S+   10:28   0:00 grep --color=auto tomcat

1.浏览器测试


2、编译安装

#下载二进制包
[root@c7-tomcat-master-51 local]# wget http://dlcdn.apache.org/tomcat/tomcat-9/v9.0.85/bin/apache-tomcat-9.0.85.tar.gz

[root@c7-tomcat-master-51 local]# tar xf apache-tomcat-9.0.85.tar.gz -C /usr/local/
[root@c7-tomcat-master-51 local]# cd /usr/local/
[root@c7-tomcat-master-51 local]# ln -s apache-tomcat-9.0.85 tomcat

[root@c7-tomcat-master-51 local]# cat /etc/profile.d/tomcat.sh 
PATH=/usr/local/tomcat/bin:$PATH
[root@c7-tomcat-master-51 local]# . /etc/profile.d/tomcat.sh

[root@c7-tomcat-master-51 local]# echo $PATH
/usr/local/tomcat/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/jdk/bin

#查看tomcat相关信息
[root@c7-tomcat-master-51 local]# catalina.sh version
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:   
Server version: Apache Tomcat/9.0.85
Server built:   Jan 5 2024 08:28:07 UTC
Server number:  9.0.85.0
OS Name:        Linux
OS Version:     3.10.0-1160.el7.x86_64
Architecture:   amd64
JVM Version:    1.8.0_391-b13
JVM Vendor:     Oracle Corporation

#启动tomcat
[root@c7-tomcat-master-51 local]# 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@c7-tomcat-master-51 local]# ps -aux | grep tomcat
avahi       681  0.0  0.0  62268  2268 ?        Ss   10:30   0:00 avahi-daemon: running [c7-tomcat-master-51.local]
root       2505 16.5  3.1 4558096 119776 pts/0  Sl   11:02   0:02 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/usr/local/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 /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start
root       2538  0.0  0.0 112812   968 pts/0    S+   11:02   0:00 grep --color=auto tomcat

#关闭tomcat
[root@c7-tomcat-master-51 local]# 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@c7-tomcat-master-51 local]# ps -aux | grep tomcat
avahi       681  0.0  0.0  62268  2268 ?        Ss   10:30   0:00 avahi-daemon: running [c7-tomcat-master-51.local]
root       2582  0.0  0.0 112812   968 pts/0    S+   11:04   0:00 grep --color=auto tomcat

1.配置service文件

#创造tomcat启动时所需要的用户
[root@c7-tomcat-master-51 ~]# useradd -r -s /sbin/nologin tomcat

#用于service确定java路径
[root@c7-tomcat-master-51 ~]# cat /usr/local/tomcat/conf/tomcat.conf 
JAVA_HOME=/usr/local/jdk

#修改属主属组
[root@c7-tomcat-master-51 ~]# chown -R tomcat:tomcat /usr/local/tomcat/

#复制就行,想了解怎么写的,简单的方法可以先去看看yum安装的service怎么写,慢慢了解
[root@c7-tomcat-master-51 ~]# cat /lib/systemd/system/tomcat.service
[Unit]
Description=Tomcat
After=syslog.target network.target 

[Service]
Type=forking
EnvironmentFile=/usr/local/tomcat/conf/tomcat.conf
ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
PrivateTmp=true
User=tomcat
Group=tomcat

[Install]
WantedBy=multi-user.target

[root@c7-tomcat-master-51 ~]# systemctl daemon-reload 
[root@c7-tomcat-master-51 ~]# systemctl enable --now tomcat
Created symlink from /etc/systemd/system/multi-user.target.wants/tomcat.service to /usr/lib/systemd/system/tomcat.service.

[root@c7-tomcat-master-51 ~]# systemctl status tomcat
● tomcat.service - Tomcat
   Loaded: loaded (/usr/lib/systemd/system/tomcat.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2024-02-14 11:07:41 CST; 22s ago
  Process: 2767 ExecStart=/usr/local/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 2775 (java)
    Tasks: 32
   CGroup: /system.slice/tomcat.service
           └─2775 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.Cl...

Feb 14 11:07:41 c7-tomcat-master-51 systemd[1]: Starting Tomcat...
Feb 14 11:07:41 c7-tomcat-master-51 systemd[1]: Started Tomcat.

2.浏览器测试



四、Tomcat文件结构

1、目录结构

bin         服务启动、停止等相关程序和文件
conf        配置文件
lib         库目录
logs        日志目录
webapps     应用程序,应用部署目录
work        jsp编译后的结果文件,建议提前预热访问,升级应用后,删除此目录数据才能更新

[root@c7-tomcat-master-51 ~]# ls -lh /usr/local/tomcat/
total 128K
drwxr-x---. 2 tomcat tomcat 4.0K Feb 14 10:58 bin
-rw-r-----. 1 tomcat tomcat  20K Jan  5 16:28 BUILDING.txt
drwx------. 3 tomcat tomcat  273 Feb 14 11:05 conf
-rw-r-----. 1 tomcat tomcat 6.1K Jan  5 16:28 CONTRIBUTING.md
drwxr-x---. 2 tomcat tomcat 4.0K Feb 14 10:58 lib
-rw-r-----. 1 tomcat tomcat  56K Jan  5 16:28 LICENSE
drwxr-x---. 2 tomcat tomcat  197 Feb 14 11:02 logs
-rw-r-----. 1 tomcat tomcat 2.3K Jan  5 16:28 NOTICE
-rw-r-----. 1 tomcat tomcat 3.4K Jan  5 16:28 README.md
-rw-r-----. 1 tomcat tomcat 6.8K Jan  5 16:28 RELEASE-NOTES
-rw-r-----. 1 tomcat tomcat  17K Jan  5 16:28 RUNNING.txt
drwxr-x---. 2 tomcat tomcat   30 Feb 14 10:58 temp
drwxr-x---. 7 tomcat tomcat   81 Jan  5 16:28 webapps
drwxr-x---. 3 tomcat tomcat   22 Feb 14 11:02 work

2、配置文件和日志

1.配置文件

server.xml          主配置文件
web.xml             每个webapp只有“部署”后才能被访问,它的部署方式通常由web.xml进行定义,其存放位置为WEB-INF/目录中;此文件为所有的webapps提供默认部署相关的配置,每个web应用也可以使用专用配置文件,来覆盖全局文件
context.xml         用于定义所有web应用均需加载的Context配置,此文件为所有的
webapps             提供默认配置,每个web应用也可以使用自已专用的配置,它通常由专用的配置文件context.xml来定义,其存放位置为WEB-INF/目录中,覆盖全局的文件
tomcat-users.xml    用户认证的账号和密码文件
catalina.policy     当使用security选项启动tomcat时,用于为tomcat设置安全策略
catalina.properties Tomcat 环境变量的配置,用于设定类加载器路径,以及一些与JVM调优相关参数
logging.properties  Tomcat 日志系统相关的配置,可以修改日志级别和日志路径等

[root@c7-tomcat-master-51 ~]# ls -1 /usr/local/tomcat/conf/
Catalina
catalina.policy
catalina.properties
context.xml
jaspic-providers.xml
jaspic-providers.xsd
logging.properties
server.xml
tomcat.conf
tomcat-users.xml
tomcat-users.xsd
web.xml

2.日志文件

tomcat有五类日志:catalina、localhost、manager、admin、host-manager

catalina.out
catalina.out即标准输出和标准出错,所有输出到这两个位置的都会进入catalina.out,这里包含tomcat运行自己输出的日志以及应用里向console输出的日志。默认这个日志文件是不会进行自动切割的,我们需要借助其他工具进行切割(注意:catalina.out文件如果过大会影响)

catalina.YYYY-MM-DD.log
catalina.{yyyy-MM-dd}.log是tomcat自己运行的一些日志,这些日志还会输出到catalina.out,但是应用向console输出的日志不会输出到catalina.{yyyy-MM-dd}.log,它是tomcat的启动和暂停时的运行日志,注意,它和catalina.out是里面的内容是不一样的。

localhost.YYYY-MM-DD.log
localhost.{yyyy-MM-dd}.log主要是应用初始化(listener, filter, servlet)未处理的异常最后被tomcat捕获而输出的日志,它也是包含tomcat的启动和暂停时的运行日志,但它没有catalina.2018-09-19.log日志全。它只是记录了部分日志。

localhost_access_log.YYYY-MM-DD.txt
这个是访问tomcat的日志,请求时间和资源,状态码都有记录。

host-manager.YYYY-MM-DD.log
这个是放tomcat的自带的manager项目的日志信息的,未看到有什么重要的日志信息。

manager.YYYY-MM-DD.log
这个是tomcat manager项目专有的日志文件

[root@c7-tomcat-master-51 ~]# ls -1 /usr/local/tomcat/logs/
catalina.2024-02-14.log
catalina.out
host-manager.2024-02-14.log
localhost.2024-02-14.log
localhost_access_log.2024-02-14.txt
manager.2024-02-14.log

3、组件

顶级组件
Server,代表整个Tomcat容器,一台主机可以启动多tomcat实例,需要确保端口不要产生冲突

服务类组件
Service,实现组织Engine和Connector,建立两者之间关联关系, service 里面只能包含一个Engine

连接器组件
Connector,有HTTP(默认端口8080/tcp)、HTTPS(默认端口8443/tcp)、AJP(默认端口8009/tcp)协议的连接器,AJP(Apache Jserv protocol)是一种基于TCP的二进制通讯协议。

容器类
Engine、Host(虚拟主机)、Context(上下文件,解决路径映射)都是容器类组件,可以嵌入其它组件,内部配置如何运行应用程序。

内嵌类
可以内嵌到其他组件内,valve、logger、realm、loader、manager等。以logger举例,在不同容器组件内分别定义。

集群类组件
listener、cluster
Server
服务器,Tomcat 运行的进程实例,一个Server中可以有多个service,但通常就一个

Service 
服务,用来组织Engine和Connector的对应关系,一个service中只有一个Engine

Connector
连接器,负责客户端的HTTP、HTTPS、AJP等协议连接。一个Connector只属于某一个Engine

Engine 
即引擎,用来响应并处理用户请求。一个Engine上可以绑定多个Connector

Host 
即虚拟主机,可以实现多虚拟主机,例如使用不同的主机头区分

Context 
应用的上下文,配置特定url路径映射和目录的映射关系:url => directory

1.核心组件

Tomcat启动一个Server进程。可以启动多个Server,即tomcat的多实例, 但一般只启动一个

创建一个Service提供服务。可以创建多个Service,但一般也只创建一个,每个Service中,是Engine和其连接器Connector的关联配置

可以为这个Service提供多个连接器Connector,这些Connector使用了不同的协议,绑定了不同的端口。其作用就是处理来自客户端的不同的连接请求或响应

Service 内部还定义了Engine,引擎才是真正的处理请求的入口,其内部定义多个虚拟主机Host
    Engine对请求头做了分析,将请求发送给相应的虚拟主机
    如果没有匹配,数据就发往Engine上的defaultHost缺省虚拟主机
    Engine上的缺省虚拟主机可以修改

Host 定义虚拟主机,虚拟主机有name名称,通过名称匹配

Context 定义应用程序单独的路径映射和配置
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Service name="Catalina">
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
               maxParameterCount="1000"
               />

    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
               maxParameterCount="1000"
               />

    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true"
               maxParameterCount="1000"
               >
    </Connector>

    <Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true"
               maxParameterCount="1000"
               >
    </Connector>

    <Connector protocol="AJP/1.3"
               address="::1"
               port="8009"
               redirectPort="8443"
               maxParameterCount="1000"
               />
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    <Engine name="Catalina" defaultHost="localhost">

          /docs/cluster-howto.html  (simple how to)
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />

             Documentation at: /docs/config/valve.html
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />
      </Host>
    </Engine>
  </Service>
</Server>

2.Tomcat 处理请求过程

假设来自客户的请求为:http://localhost:8080/test/index.jsp

浏览器端的请求被发送到服务端端口8080,Tomcat进程监听在此端口上。通过侦听的HTTP/1.1 
Connector获得此请求。
Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的响应
Engine获得请求localhost:8080/test/index.jsp,遍历它所有虚拟主机Host
Engine匹配到名为localhost的Host。如果匹配不到,就把请求交给该Engine中的defaultHost处理
localhost Host获得请求/test/index.jsp,匹配它所拥有的所有Context
Host匹配到路径为/test的Context
path=/test的Context获得请求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对象返回给浏览器端


五、Java应用部署

1、tomcat的根目录结构

Tomcat中默认网站根目录是$CATALINA_BASE/webapps/

在Tomcat中部署主站应用程序和其他应用程序,和之前WEB服务程序不同。

nginx

假设在nginx中部署2个网站应用eshop、forum,假设网站根目录是/data/nginx/html,那么部署可以 是这样的。

eshop解压缩所有文件放到 /data/nginx/html/ 目录下,forum 的文件放 在 /data/nginx/html/forum/ 下。

最终网站链接有以下对应关系

http://localhost/ 对应于eshop的应用,即 /data/nginx/html/
http://localhost/forum/ 对应于forum的应用,即/data/nginx/html/forum/
Tomcat

Tomcat中默认网站根目录是$CATALINA_BASE/webapps/

在Tomcat的webapps目录中,有个非常特殊的目录ROOT,它就是网站默认根目录。

将eshop解压后的文件放到这个$CATALINA_BASE/webapps/ROOT中。

bbs解压后文件都放在$CATALINA_BASE/webapps/forum目录下。

$CATALINA_BASE/webapps下面的每个目录都对应一个Web应用,即WebApp

最终网站链接有以下对应关系

http://localhost/ 对应于eshop的应用WebApp,即$CATALINA_BASE/webapps/ROOT/目录,
http://localhost/forum/ 对应于forum的应用WebApp,即$CATALINA_BASE/webapps/forum/

如果同时存在$CATALINA_BASE /webapps/ROOT/forum ,仍以 $CATALINA_BASE/webapps/forum/ 优先生效


2、JSP WebAPP目录结构

$CATALINA_BASE/webapps下面的每个目录对应的WebApp,可能有以下子目录,但下面子目录是非必须的

主页配置:默认按以下顺序查找主页文件 index.html,index.htm、index.jsp
WEB-INF/:当前目录WebApp的私有资源路径,通常存储当前应用使用的web.xml和context.xml配置文件
META-INF/:类似于WEB-INF,也是私有资源的配置信息,和WEB-INF/目录一样浏览器无法访问
classes/:类文件,当前webapp需要的类
lib/:当前应用依赖的jar包

3、主页设置

1.全局配置实现修改默认主页文件

默认情况下 tomcat 会在$CATALINA_BASE/webapps/ROOT/目录下按以下次序查找文件,找到第一个则进行显示
index.html
index.htm
index.jsp

[root@c7-tomcat-master-51 ~]# ls /usr/local/tomcat/webapps/ROOT/ -1 
asf-logo-wide.svg
bg-button.png
bg-middle.png
bg-nav.png
bg-upper.png
favicon.ico
index.jsp
RELEASE-NOTES.txt
tomcat.css
tomcat.svg
WEB-INF

可以通过修改 $CATALINA_BASE/conf/web.xml 中的下面 <welcome-file-list>标签 内容修改默认页文件

[root@c7-tomcat-master-51 ~]# tail /usr/local/tomcat/conf/web.xml 
  <!-- here, so be sure to include any of the default values that you wish  -->
  <!-- to use within your application.                                       -->
    #解析按顺序执行
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

2.WebApp的专用配置文件

将上面主配置文件conf/web.xml中的 标签 内容

复制到/usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml中,如下所示:

[root@c7-tomcat-master-51 ~]# tail /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml 
  <display-name>Welcome to Tomcat</display-name>
  <description>
     Welcome to Tomcat
  </description>
  <welcome-file-list>
     <welcome-file>index.html</welcome-file>   #修改三个文件的顺序
     <welcome-file>index.htm</welcome-file>
     <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

配置规则:

webApp的专有配置优先于系统的全局配置

修改系统的全局配置文件,需要重新启动服务生效

修改 webApp的专有配置,无需重启即可生效


4、应用部署实现

1.WebApp应用的归档格式

.war:WebApp打包,类zip格式文件,通常包括一个应用的所有资源,比如jsp,html,配置文件等
.jar:EJB类文件的打包压缩类zip格式文件,,包括很多的class文件, 网景公司发明
.rar:资源适配器类打包文件,目前已不常用
.ear:企业级WebApp打包,目前已不常用

传统应用开发测试后,通常打包为war格式,这种文件部署到Tomcat的webapps目录下,并默认会自动 解包展开和部署上线。

#conf/server.xml中文件配置
<Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">

2.部署方式

部署Deploy:将webapp的源文件放置到目标目录,通过web.xml和context.xml文件中配置的路径就可以访问该webapp,通过类加载器加载其特有的类和依赖的类到JVM上,即:最终用户可以通过浏览器访问该应用
    自动部署:Tomcat一旦发现多了一个web应用APP.war包,默认会自动把它解压缩,加载并启动起来
    手动部署:
        冷部署:将webapp放到指定目录,才去启动Tomcat服务
        热部署:Tomcat服务不停止,需要依赖manager、ant脚本、tcd(tomcat client deployer)等工具

反部署 undeploy:停止webapp运行,并从JVM上清除已经加载的类,从Tomcat应用目录中移除部署的文件

启动 start:启用 webapp 能够访问

停止 stop:禁用 webapp 不能访问,不能提供服务,但是JVM并不清除它

3.部署WebApp的目录结构

常见开发项目目录组成

#目录结构一般由开发用工具自动生成,以下模拟生成相关目录
mkdir projects/myapp/{WEB-INF,META-INF,classes,lib} -pv
mkdir: 已创建目录 "projects"
mkdir: 已创建目录 "projects/myapp"
mkdir: 已创建目录 "projects/myapp/WEB-INF"
mkdir: 已创建目录 "projects/myapp/META-INF"
mkdir: 已创建目录 "projects/myapp/classes"
mkdir: 已创建目录 "projects/myapp/lib"

#常见应用首页,内容就用前面的test.jsp内部
vi projects/myapp/index.jsp 

#手动复制项目目录到webapps目录下去
cp -r projects/myapp/ /usr/local/tomcat/webapps/

#注意权限和属性
chown -R tomcat.tomcat /usr/local/tomcat/webapps/myapp

#访问http://YourIP:8080/myapp/

4.JPress WebApp部署练习

#JPress官网,不过需要关注JPress公众号
https://www.jpress.cn/club/post/116

[root@c7-tomcat-master-51 ~]# cd /usr/local/tomcat/webapps/

[root@c7-tomcat-master-51 webapps]# ll 
total 119028
drwxr-x---. 16 tomcat tomcat      4096 Feb 14 10:58 docs
drwxr-x---.  7 tomcat tomcat        99 Feb 14 10:58 examples
drwxr-x---.  6 tomcat tomcat        79 Feb 14 10:58 host-manager
drwxr-x---.  6 tomcat tomcat        86 Feb 14 12:42 jpress-v5.1.0
-rw-r--r--.  1 root   root   121880224 Feb 14 12:42 jpress-v5.1.0.war
drwxr-x---.  6 tomcat tomcat       114 Feb 14 10:58 manager
drwxr-x---.  3 tomcat tomcat       223 Feb 14 10:58 ROOT

[root@c7-tomcat-master-51 webapps]# ln -s jpress-v5.1.0 jpress

[root@c7-tomcat-master-51 webapps]# ls -1 jpress
META-INF
robots.txt
static
templates
WEB-INF

#配置mysql的yum源
[root@c7-tomcat-master-51 webapps]# cat /etc/yum.repos.d/mysql.repo
[mysql]
name=mysql5.7
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-5.7-community-el7-x86_64/
gpgcheck=0

[root@c7-tomcat-master-51 webapps]# yum -y install mysql-community-server
[root@c7-tomcat-master-51 webapps]# systemctl enable --now mysqld

#获取mysql初始化密码
[root@c7-tomcat-master-51 webapps]# cat /var/log/mysqld.log |grep pass
2024-02-14T04:51:31.818837Z 1 [Note] A temporary password is generated for root@localhost: -22-g%*/Z>hQ

[root@c7-tomcat-master-51 webapps]# mysql -uroot -p'-22-g%*/Z>hQ'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.44

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 

#密码太过简单
mysql> alter user root@'localhost' identified by '123456';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements

#登陆进去后先修够root密码
mysql> alter user root@'localhost' identified by 'Jtq123..';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

#创造JPress需要的库和用户
mysql> create database jpress;
Query OK, 1 row affected (0.00 sec)

mysql> create user jpress@'%' identified by 'Jtq123..';
Query OK, 0 rows affected (0.00 sec)

mysql> grant all on jpress.* to jpress@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

浏览器配置


5.基于WEB的管理Server status和Manager APP实现应用部署

实现WEB的管理Server status和Manager APP

[root@c7-tomcat-master-51 webapps]# cat /usr/local/tomcat/webapps/manager/META-INF/context.xml 
<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true" >
  <CookieProcessor className="org.apache.tomcat.util.http.Rfc6265CookieProcessor"
                   sameSiteCookies="strict" />
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
            #修改此行添加|172\.29\.\d+.\d+
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|172\.29\.\d+\.\d+" />
  <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>
[root@c7-tomcat-master-51 webapps]# cat /usr/local/tomcat/conf/tomcat-users.xml 
<?xml version="1.0" encoding="UTF-8"?>

<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
#添加两行
  <role rolename="manager-gui"/>
  <user username="admin" password="123456" roles="manager-gui"/>
</tomcat-users>

基于WEB应用程序管理器实现APP的部署

Web 应用程序管理界面可以实现以下功能

Applications 应用程序管理,可以启动、停止、重加载、反部署、清理过期session

Deploy 可以热部署,也可以部署war文件。

[root@c7-tomcat-master-51 webapps]# mkdir -p /data/myapp/
[root@c7-tomcat-master-51 webapps]# echo /data/myapp/index.html > /data/myapp/index.html
Context Path (required): 指定通过浏览器访问的虚拟目录
WAR or Directory URL:指定真正存放文件的实际磁盘目录路径

6.常见配置详解

端口8005/tcp 安全配置管理

在conf/server.xml 有以下内容

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <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">
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
      </Host>
    </Engine>
  </Service>
</Server>
<Server port="8005" shutdown="SHUTDOWN">

8005是Tomcat的管理端口,默认监听在127.0.0.1上。无需验证就可发送SHUTDOWN (大小写敏感)这个 字符串,tomcat接收到后就会关闭此Server。

此管理功能建议禁用,可将SHUTDOWN改为一串猜不出的字符串实现

或者port修改成 0, 会使用随机端口,如:36913

port设为-1等无效端口,将关闭此功能,注意:-2等不支持

此行不能被注释,否则无法启动tomcat服务


显示指定的http服务器版本信息

默认不显示tomcat的http的Server头信息, 可以指定tomcat的http的Server头信息为相应的值

#conf/server.xml
<Connector port="8080" protocol="HTTP/1.1"  connectionTimeout="20000"
redirectPort="8443" Server="SOME STRING"/> 
[root@c7-tomcat-master-51 tomcat]# curl -I 127.0.0.1:8080
HTTP/1.1 200 
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 14 Feb 2024 06:26:22 GMT

[root@c7-tomcat-master-51 tomcat]# vim /usr/local/tomcat/conf/server.xml 
....
<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
               maxParameterCount="1000"
               Server="nginx"
               />
....

#java的启动时间比较长,先不要怀疑自己是否做错了
[root@c7-tomcat-master-51 tomcat]# systemctl restart tomcat

[root@c7-tomcat-master-51 tomcat]# curl -I 127.0.0.1:8080
HTTP/1.1 200 
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Wed, 14 Feb 2024 06:28:41 GMT
Server: nginx

其他配置

service配置

一般情况下,一个Server实例配置一个Service,name属性相当于该Service的ID。

<Service name="Catalina">

连接器配置

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

redirectPort,如果访问HTTPS协议,自动转向这个连接器。但大多数时候,Tomcat并不会开启 HTTPS,因为Tomcat往往部署在内部HTTPS性能较差


引擎配置

<Engine name="Catalina" defaultHost="localhost">

defaultHost 配置

defaultHost指向内部定义某虚拟主机。缺省虚拟主机可以改动,默认localhost。

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

多虚拟主机配置

多虚拟主机配置说明

name 必须是主机名,用主机名来匹配
appBase 当前主机的网页根目录,是相对于 $CATALINA_HOME ,也可以使用绝对路径
unpackWARs 是否自动解压war格式
autoDeploy 热部署,自动加载并运行应用

虚拟主机配置过程

再添加和配置一个新的虚拟主机,并将myapp部署到/data/webapps目录下

[root@c7-tomcat-master-51 tomcat]# vim /usr/local/tomcat/conf/server.xml 
....
#在文件最后面增加下面内容
<Host name="web1.wang.org" appBase="/data/webapps/" unpackWARs="True"
autoDeploy="false">
#虚拟主机专有访问日志
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="web1_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s 
%b" />
</Host>

#以下行是自带的不需要修改
</Engine>
</Service>
</Server>   

基于web方式的Host Manager虚拟主机管理

可以通过tomcat的管理页面点下面Host Manager按钮进入管理虚拟主机的页面

[root@c7-tomcat-master-51 tomcat]# cat webapps/host-manager/META-INF/context.xml 
<?xml version="1.0" encoding="UTF-8"?>

<Context antiResourceLocking="false" privileged="true" >
  <CookieProcessor className="org.apache.tomcat.util.http.Rfc6265CookieProcessor"
                   sameSiteCookies="strict" />
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|172\.29\.\d+\.\d+" />
  <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>
[root@c7-tomcat-master-51 tomcat]# cat conf/tomcat-users.xml 
<?xml version="1.0" encoding="UTF-8"?>

<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">

  <role rolename="manager-gui"/>
  <role rolename="admin-gui"/>
  <user username="admin" password="123456" roles="manager-gui,admin-gui"/>
</tomcat-users>


六、结合反向代理实现 Tomcat 部署

可以利用iptables策略实现端口重定向或DNAT,解决非标准端口的问题

iptables -t nat -A PREROUTING -p tcp --dport 80 --j REDIRECT --to-port 8080

1、常见部署方式介绍

standalone模式,Tomcat单独运行,直接接受用户的请求,不推荐。

反向代理,单机运行,提供了一个Nginx作为反向代理,可以做到静态由nginx提供响应,动态jsp 代理给Tomcat 
LNMT:Linux + Nginx + MySQL + Tomcat 
LAMT:Linux + Apache(Httpd)+ MySQL + Tomcat

前置一台Nginx,给多台Tomcat实例做反向代理和负载均衡调度,Tomcat上部署的纯动态页面更 适合 
LNMT:Linux + Nginx + MySQL + Tomcat

多级代理 
LNNMT:Linux + Nginx + Nginx + MySQL + Tomcat

用nginx指令proxy_pass 可以向后端服务器转发请求报文,并且在转发时会保留客户端的请求报文中的 host首部

#从yum源安装nginx
#yum install nginx -y
#vim /etc/nginx/nginx.conf
#全部反向代理测试
location / {
    # proxy_pass http://127.0.0.1:8080; # 不管什么请求,都会访问后面的localhost虚拟主机
   proxy_pass http://node1.tomcat.com:8080; # 此项将用户访问全部请求转发到node1的虚拟主机上
    #proxy_pass http://node2.tomcat.com:8080; #此项将用户访问全部请求转发到node2的虚拟主机上
    #proxy_set_header Host $http_host; #转发主机头至后端服务器

    #以上两项都需要修改nginx服务器的/etc/hosts,实现node1.tomcat.com和node2.tomcat.com到IP的解析    
}

#nginx -t
#systemctl restart nginx

#说明: proxy_pass http://FQDN/ 中的FQDN 决定转发至后端哪个虚拟主机,而与用户请求的URL无关

#如果转到后端的哪个服务器由用户请求决定,可以向后端服务转发请求的主机头实现,示例: 
proxy_set_header Host $http_host; 

2、实现 HTTPS

[root@c7-nginx-master-31 ~]# cat /apps/nginx/conf/nginx.conf
.....

    server {
        listen       80;
        server_name  www.jiutingqiu.com;

        #访问http后直接转到https
        return 302 https://$host$request_uri;

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

.....
    }

......
    server {
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate      /data/www.jiutingqiu.com.pem;
        ssl_certificate_key  /data/www.jiutingqiu.com.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
        proxy_pass http://172.29.7.51:8080;
        proxy_set_header Host $http_host;   #把原来http请求头里的Host字段也转过来
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    #获得用户的真实ip
        }
    }
.....
}

#nginx语法检查
[root@c7-nginx-master-31 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful

3、实现 Tomcat 负载均衡

动态服务器的问题,往往就是并发能力太弱,往往需要多台动态服务器一起提供服务。如何把并发的压 力分摊,这就需要调度,采用一定的调度策略,将请求分发给不同的服务器,这就是Load Balance负载 均衡。 当单机Tomcat,演化出多机多级部署的时候,一个问题便凸显出来,这就是Session。而这个问题的由 来,都是由于HTTP协议在设计之初没有想到未来的发展。

1.HTTP的无状态,有连接和短连接

无状态:指的是服务器端无法知道2次请求之间的联系,即使是前后2次请求来自同一个浏览器,也没有任何数据能够判断出是同一个浏览器的请求。后来可以通过cookie、session机制来判断。
    浏览器端第一次HTTP请求服务器端时,在服务器端使用session这种技术,就可以在服务器端产生一个随机值即SessionID发给浏览器端,浏览器端收到后会保持这个SessionID在Cookie当中,这个Cookie值一般不能持久存储,浏览器关闭就消失。浏览器在每一次提交HTTP请求的时候会把这个SessionID传给服务器端,服务器端就可以通过比对知道是谁了
    Session通常会保存在服务器端内存中,如果没有持久化,则易丢失
    Session会定时过期。过期后浏览器如果再访问,服务端发现没有此ID,将给浏览器端重新发
    新的SessionID
    更换浏览器也将重新获得新的SessionID

有连接:是因为它基于TCP协议,是面向连接的,需要3次握手、4次断开。

短连接:Http 1.1之前,都是一个请求一个连接,而Tcp的连接创建销毁成本高,对服务器有很大的影响。所以,自Http 1.1开始,支持keep-alive,默认也开启,一个连接打开后,会保持一段时间(可设置),浏览器再访问该服务器就使用这个Tcp连接,减轻了服务器压力,提高了效率。

服务器端如果故障,即使Session被持久化了,但是服务没有恢复前都不能使用这些SessionID。

如果使用HAProxy或者Nginx等做负载均衡器,调度到了不同的Tomcat上,那么也会出现找不到SessionID的情况。

2.会话保持方式

Session sticky 会话黏性

Session绑定
    nginx:source ip, cookie
    HAProxy:source ip, cookie

优点:简单易配置
缺点:如果目标服务器故障后,如果没有做sessoin持久化,就会丢失session,此方式生产很少使用

Session 复制集群

Tomcat自己的提供的多播集群,通过多播将任何一台的session同步到其它节点。
缺点
    Tomcat的同步节点不宜过多,互相即时通信同步session需要太多带宽
    每一台都拥有全部session,内存损耗太多

Session Server

session 共享服务器,使用memcached、redis做共享的Session服务器,此为推荐方式

4、负载均衡规划和准备

1.负载均衡主机和网络地址规划

IP 主机名 服务 程序
172.29.7.31 c7-nginx-master-31 调度器 Nginx
172.29.7.51 c7-tomcat-master-51 tomcat1 JDK8、Tomcat8
172.29.7.52 c7-tomcat-slave-52 tomcat2 JDK8、Tomcat8

2.配置index.html文件

[root@c7-tomcat-master-51 ~]# echo tomcat node1 51 > /usr/local/tomcat/webapps/ROOT/index.html
[root@c7-tomcat-slave-52 ~]# echo tomcat node2 52 > /usr/local/tomcat/webapps/ROOT/index.html

3.Nginx配置

[root@c7-nginx-master-31 ~]# cat /apps/nginx/conf/nginx.conf
.....
http {
.....

    upstream tomcat-server {
    #ip_hash;         # 先禁用看看轮询,之后开启开黏性,只根据客户端IP的前三位十进制数字
    #hash $remote_addr consistent;       # 根据客户端IP的全部位
    #hash $cookie_JSESSIONID consistent; # 先禁用看看轮询,之后开启开黏性,JSESSIONID可以小写
    server 172.29.7.51:8080;
    server 172.29.7.52:8080;
    }

    server {
        listen       80;
        server_name  www.jiutingqiu.com;
        location ~* \.(jsp|do)$ {
            proxy_pass http://tomcat-server;
            #proxy_set_header Host $http_host; #转发主机头至后端服务器
        }
        #return 302 https://$host$request_uri;

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        .....
    }
.....

[root@c7-nginx-master-31 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful

[root@c7-nginx-master-31 ~]# nginx -s reload

4.测试

[root@c7-nginx-master-31 ~]# curl 127.0.0.1:80
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.22.1</center>
</body>
</html>

[root@c7-nginx-master-31 ~]# curl  -L  172.29.7.31
tomcat node2 52
[root@c7-nginx-master-31 ~]# curl  -L  172.29.7.31
tomcat node1 51

5.接下来就是分情况使用这些会话保持选项

#ip_hash;         # 先禁用看看轮询,之后开启开黏性,只根据客户端IP的前三位十进制数字
#hash $remote_addr consistent;       # 根据客户端IP的全部位
#hash $cookie_JSESSIONID consistent; # 先禁用看看轮询,之后开启开黏性,JSESSIONID可以小写


七、Tomcat Session Replication Cluster(Tomcat Session复制集群)

Tomcat 官方实现了 Session 的复制集群,将每个Tomcat的Session进行相互的复制同步,从而保证所有 Tomcat都有相同的Session信息.


1、配置说明

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
            channelSendOptions="8">

    <Manager className="org.apache.catalina.ha.session.DeltaManager"
                expireSessionsOnShutdown="false"
                notifyListenersOnReplication="true"/>

    <Channel className="org.apache.catalina.tribes.group.GroupChannel">
        <Membership className="org.apache.catalina.tribes.membership.McastService"
                    address="228.0.0.4"         #指定的多播地址
                    port="45564"   #45564/UDP
                    frequency="500"             #间隔500ms发送
                    dropTime="3000"/>           #故障阈值3s
        <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                    address="auto"   #监听地址,此项建议修改为当前主机的IP(不支持0.0.0.0),如果不修改可能会导致服务无法启动
                    port="4000" #监听端口
                    autoBind="100" #如果端口冲突,自动绑定其它端口,范围是4000-4100
                    selectorTimeout="5000"        #自动绑定超时时长5s
                    maxThreads="6"/>
        <Sender 
className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
        <Transport 
className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
        </Sender>
        <Interceptor 
className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
        <Interceptor 
className="org.apache.catalina.tribes.group.interceptors.MessageDispatchIntercep
tor"/>
</Channel>

    <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
    <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

    <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                tempDir="/tmp/war-temp/"
                deployDir="/tmp/war-deploy/"
                watchDir="/tmp/war-listen/"
                watchEnabled="false"/>

 <ClusterListener 
className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>
Cluster 集群配置
Manager 会话管理器配置
Channel 信道配置
    Membership 成员判定。使用什么多播地址、端口多少、间隔时长ms、超时时长ms。同一个多播地址和端口认为同属一个组。使用时修改这个多播地址,以防冲突
    Receiver 接收器,多线程接收多个其他节点的心跳、会话信息。默认会从4000到4100依次尝试可用端口
        address="auto",auto可能绑定到127.0.0.1上,所以一定要改为当前主机可用的IP
    Sender 多线程发送器,内部使用了tcp连接池。
    Interceptor 拦截器
Valve 
    ReplicationValve 检测哪些请求需要检测Session,Session数据是否有了变化,需要启动复制过程
ClusterListener
    ClusterSessionListener 集群session侦听器

使用 <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

添加到 <Engine> 所有虚拟主机都可以启用Session复制

添加到 <Host> ,该虚拟主机可以启用Session复制

最后,在应用程序内部启用了才可以使用

2、修改应用目录下的 WEB-INF/web.xml

注意: 不要修改 conf/web.xml,此文件不起作用
注意:WEB-INF/web.xml文件的如果权限不对,会导致复制失败

</description>
<distributable/> #添加此行
</web-app>

3、练习测试

1.Tomcat Session Replication Cluster规划和准备

IP 主机名 服务 程序
172.29.7.31 c7-nginx-master-31 调度器 Nginx
172.29.7.51 c7-tomcat-master-51 tomcat1 JDK8、Tomcat8
172.29.7.52 c7-tomcat-slave-52 tomcat2 JDK8、Tomcat8

2.Nginx配置

[root@c7-nginx-master-31 ~]# cat /apps/nginx/conf/nginx.conf
.....
http {
.....

    upstream tomcat-server {
    #ip_hash;         # 先禁用看看轮询,之后开启开黏性,只根据客户端IP的前三位十进制数字
    #hash $remote_addr consistent;       # 根据客户端IP的全部位
    #hash $cookie_JSESSIONID consistent; # 先禁用看看轮询,之后开启开黏性,JSESSIONID可以小写
    server 172.29.7.51:8080;
    server 172.29.7.52:8080;
    }

    server {
        listen       80;
        server_name  www.jiutingqiu.com;
        location ~* \.(jsp|do)$ {
            proxy_pass http://tomcat-server;
            #proxy_set_header Host $http_host; #转发主机头至后端服务器
        }
        #return 302 https://$host$request_uri;

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        .....
    }
.....

[root@c7-nginx-master-31 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful

[root@c7-nginx-master-31 ~]# nginx -s reload

3.Tomcat后端配置

c7-tomcat-master-51

[root@c7-tomcat-master-51 ~]# cat /usr/local/tomcat/conf/server.xml 
.......
#<Host></Host>模块中添加

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
    <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
            channelSendOptions="8">

    <Manager className="org.apache.catalina.ha.session.DeltaManager"
                expireSessionsOnShutdown="false"
                notifyListenersOnReplication="true"/>

    <Channel className="org.apache.catalina.tribes.group.GroupChannel">
        <Membership className="org.apache.catalina.tribes.membership.McastService"
                    address="230.100.100.100" #指定不冲突的多播地址
                    port="45564"
                    frequency="500"
                    dropTime="3000"/>
        <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                    address="172.29.7.51"     #监听地址,此项建议修改为当前主机的IP,如果不修改可能会导致服务无法启动
                    port="4000"
                    autoBind="100"
                    selectorTimeout="5000"
                    maxThreads="6"/>
        <Sender 
className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
        <Transport 
className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
        </Sender>
        <Interceptor 
className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
        <Interceptor 
className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
</Channel>

    <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
    <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

    <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                tempDir="/tmp/war-temp/"
                deployDir="/tmp/war-deploy/"
                watchDir="/tmp/war-listen/"
                watchEnabled="false"/>

 <ClusterListener 
className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

#到这

        <!-- 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" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />

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

#重启需要一点时间
[root@c7-tomcat-master-51 ~]# systemctl restart tomcat
[root@c7-tomcat-master-51 ~]# systemctl status tomcat
● tomcat.service - Tomcat
   Loaded: loaded (/usr/lib/systemd/system/tomcat.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2024-02-14 17:15:55 CST; 971ms ago
  Process: 3152 ExecStop=/usr/local/tomcat/bin/shutdown.sh (code=exited, status=0/SUCCESS)
  Process: 3207 ExecStart=/usr/local/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 3216 (java)
    Tasks: 23
   CGroup: /system.slice/tomcat.service
           └─3216 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.Cl...

Feb 14 17:15:55 c7-tomcat-master-51 systemd[1]: Starting Tomcat...
Feb 14 17:15:55 c7-tomcat-master-51 systemd[1]: Started Tomcat.

#出错翻找catalina日志
[root@c7-tomcat-master-51 ~]# cat /usr/local/tomcat/logs/catalina.2024-02-14.log 

[root@c7-tomcat-master-51 ~]# scp /usr/local/tomcat/conf/server.xml root@172.29.7.52:/usr/local/tomcat/conf/server.xml 

[root@c7-tomcat-master-51 ~]# tail -n 3 /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml 
  </description>
<distributable/>  #添加此行
</web-app>

c7-tomcat-slave-52

[root@c7-tomcat-master-52 ~]# cat /usr/local/tomcat/conf/server.xml 
.......
#<Host></Host>模块中添加

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
    <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
            channelSendOptions="8">

    <Manager className="org.apache.catalina.ha.session.DeltaManager"
                expireSessionsOnShutdown="false"
                notifyListenersOnReplication="true"/>

    <Channel className="org.apache.catalina.tribes.group.GroupChannel">
        <Membership className="org.apache.catalina.tribes.membership.McastService"
                    address="230.100.100.100" 
                    port="45564"
                    frequency="500"
                    dropTime="3000"/>
        <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                    address="172.29.7.51"     #此行指定当前主机的IP,其它和T1节点配置相同
                    port="4000"
                    autoBind="100"
                    selectorTimeout="5000"
                    maxThreads="6"/>
        <Sender 
className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
        <Transport 
className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
        </Sender>
        <Interceptor 
className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
        <Interceptor 
className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
</Channel>

    <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>
    <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

    <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                tempDir="/tmp/war-temp/"
                deployDir="/tmp/war-deploy/"
                watchDir="/tmp/war-listen/"
                watchEnabled="false"/>

 <ClusterListener 
className="org.apache.catalina.ha.session.ClusterSessionListener"/>
</Cluster>

#到这

        <!-- 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" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />

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

[root@c7-tomcat-master-52 ~]# tail -n 3 /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml 
  </description>
<distributable/>  #添加此行
</web-app>

出错翻找catalina日志


[root@c7-tomcat-master-52 ~]# cat /usr/local/tomcat/logs/catalina.2024-02-14.log 
    #lineNumber: 192; columnNumber: 7; Error at line [192] col 这个就是错误

    org.xml.sax.SAXParseException; systemId: file:/usr/local/apache-tomcat-9.0.85/conf/server.xml; lineNumber: 192; columnNumber: 7; Error at line [192] col     umn [7]: [org.apache.catalina.tribes.group.interceptors.MessageDispatchIntercep tor]
2596                 at org.apache.tomcat.util.digester.Digester.createSAXException(Digester.java:1966)
2597                 at org.apache.tomcat.util.digester.Digester.createSAXException(Digester.java:1998)
2598                 at org.apache.tomcat.util.digester.Digester.startElement(Digester.java:1280)
2599                 at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:510)
2600                 at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:183)
2601                 at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1341)
2602                 at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2786)
2603                 at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:605)
2604                 at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:507)
2605                 at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:867)
2606                 at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:796)
2607                 at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:142)
2608                 at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1216)
2609                 at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:644)
2610                 at org.apache.tomcat.util.digester.Digester.parse(Digester.java:1535)
2611                 at org.apache.catalina.startup.Catalina.parseServerXml(Catalina.java:617)
2612                 at org.apache.catalina.startup.Catalina.load(Catalina.java:709)
2613                 at org.apache.catalina.startup.Catalina.load(Catalina.java:746)


八、Memcached

Memcached 只支持能序列化的数据类型,不支持持久化,基于Key-Value的内存缓存系统

Memcached 借助了操作系统的 libevent 工具做高效的读写。libevent是个程序库,它将Linux的 epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也 能发挥高性能。

memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其 高性能 Memcached 支持最大的内存存储对象为1M,超过1M的数据可以使用客户端压缩或拆分报包放到多个 key中,比较大的数据在进行读取的时候需要消耗的时间比较长,memcached 最适合保存用户的 session实现session共享

Memcached存储数据时, Memcached会去申请1MB的内存, 把该块内存称为一个slab, 也称为一个page


1、Memcached安装

1.yum安装

[root@c7-memcached-61 ~]# yum list memcached --showduplicates
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: mirrors.bupt.edu.cn
 * extras: mirrors.bupt.edu.cn
 * updates: mirrors.bupt.edu.cn
Available Packages
memcached.x86_64

[root@c7-memcached-61 ~]# yum -y install memcached

[root@c7-memcached-61 ~]# rpm -ql memcached
/etc/sysconfig/memcached
/usr/bin/memcached
/usr/bin/memcached-tool
/usr/lib/systemd/system/memcached.service
/usr/share/doc/memcached-1.4.15
/usr/share/doc/memcached-1.4.15/AUTHORS
/usr/share/doc/memcached-1.4.15/CONTRIBUTORS
/usr/share/doc/memcached-1.4.15/COPYING
/usr/share/doc/memcached-1.4.15/ChangeLog
/usr/share/doc/memcached-1.4.15/NEWS
/usr/share/doc/memcached-1.4.15/README.md
/usr/share/doc/memcached-1.4.15/protocol.txt
/usr/share/doc/memcached-1.4.15/readme.txt
/usr/share/doc/memcached-1.4.15/threads.txt
/usr/share/man/man1/memcached-tool.1.gz
/usr/share/man/man1/memcached.1.gz

2.编译安装

[root@c7-memcached-61 ~]# yum -y install gcc libevent-devel

[root@c7-memcached-61 ~]# wget http://www.memcached.org/files/memcached-1.6.23.tar.gz

[root@c7-memcached-61 ~]# tar xvf memcached-1.6.23.tar.gz
[root@c7-memcached-61 ~]# cd memcached-1.6.23/
[root@c7-memcached-61 memcached-1.6.23]# ./configure --prefix=/apps/memcached
[root@c7-memcached-61 memcached-1.6.23]# make && make install

[root@c7-memcached-61 memcached-1.6.23]# tree /apps/memcached/
/apps/memcached/
├── bin
│   └── memcached
├── include
│   └── memcached
│       ├── protocol_binary.h
│       └── xxhash.h
└── share
    └── man
        └── man1
            └── memcached.1

6 directories, 4 files

[root@c7-memcached-61 memcached-1.6.23]# echo 'PATH=/apps/memcached/bin:$PATH' > /etc/profile.d/memcached.sh
[root@c7-memcached-61 memcached-1.6.23]# . /etc/profile.d/memcached.sh 
[root@c7-memcached-61 memcached-1.6.23]# echo $PATH
/apps/memcached/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

3.service文件编写

[root@c7-memcached-61 memcached-1.6.23]# useradd -r -s /sbin/nologin memcached

[root@c7-memcached-61 memcached-1.6.23]# vim /etc/sysconfig/memcached
[root@c7-memcached-61 memcached-1.6.23]# cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 127.0.0.1,::1"

[root@c7-memcached-61 memcached-1.6.23]# cat /lib/systemd/system/memcached.service
[Unit]
Description=memcached daemon
Before=httpd.service
After=network.target

[Service]
EnvironmentFile=/etc/sysconfig/memcached
ExecStart=/apps/memcached/bin/memcached -p ${PORT} -u ${USER} -m ${CACHESIZE} -c ${MAXCONN} $OPTIONS

[Install]
WantedBy=multi-user.target

[root@c7-memcached-61 memcached-1.6.23]# systemctl daemon-reload 
[root@c7-memcached-61 memcached-1.6.23]# systemctl enable --now memcached.service
Created symlink from /etc/systemd/system/multi-user.target.wants/memcached.service to /usr/lib/systemd/system/memcached.service.

[root@c7-memcached-61 memcached-1.6.23]# systemctl status memcached.service 
● memcached.service - memcached daemon
   Loaded: loaded (/usr/lib/systemd/system/memcached.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2024-02-15 10:02:25 CST; 28s ago
 Main PID: 4640 (memcached)
    Tasks: 10
   CGroup: /system.slice/memcached.service
           └─4640 /apps/memcached/bin/memcached -p 11211 -u memcached -m 64 -c 1024 -l 127.0.0.1,::1

Feb 15 10:02:25 c7-memcached-61 systemd[1]: Started memcached daemon.

[root@c7-memcached-61 memcached-1.6.23]# memcached --version
memcached 1.6.23

2、memcached 启动程序说明

修改memcached 运行参数,可以使用下面的选项修改/etc/sysconfig/memcached文件

memcached 常见选项

-u username memcached运行的用户身份,必须普通用户
-p 绑定的端口,默认11211
-m num 最大内存,单位MB,默认64MB
-c num 最大连接数,缺省1024
-d 守护进程方式运行
-f 增长因子Growth Factor,默认1.25
-v 详细信息,-vv能看到详细信息
-M 使用内存直到耗尽,不许LRU
-U 设置UDP监听端口,0表示禁用UDP

3、使用 memcached

memcached工具

[root@c7-memcached-61 memcached-1.6.23]# yum list libmemcached --showduplicates
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * base: mirrors.bupt.edu.cn
 * extras: mirrors.bupt.edu.cn
 * updates: mirrors.bfsu.edu.cn
Available Packages
libmemcached.i686                                                                   1.0.16-5.el7                                                                 base
libmemcached.x86_64                                                                 1.0.16-5.el7

[root@c7-memcached-61 memcached-1.6.23]# yum -y install libmemcached

[root@c7-memcached-61 memcached-1.6.23]# rpm -ql libmemcached
/usr/bin/memaslap
/usr/bin/memcapable
/usr/bin/memcat
/usr/bin/memcp
/usr/bin/memdump
/usr/bin/memerror
/usr/bin/memexist
/usr/bin/memflush
/usr/bin/memparse
/usr/bin/memping
/usr/bin/memrm
/usr/bin/memslap
/usr/bin/memstat
/usr/bin/memtouch
/usr/lib64/libhashkit.so.2
/usr/lib64/libhashkit.so.2.0.0
/usr/lib64/libmemcached.so.11
/usr/lib64/libmemcached.so.11.0.0
/usr/lib64/libmemcachedprotocol.so.0
/usr/lib64/libmemcachedprotocol.so.0.0.0
/usr/lib64/libmemcachedutil.so.2
/usr/lib64/libmemcachedutil.so.2.0.0
/usr/share/doc/libmemcached-1.0.16
/usr/share/doc/libmemcached-1.0.16/AUTHORS
/usr/share/doc/libmemcached-1.0.16/COPYING
/usr/share/doc/libmemcached-1.0.16/ChangeLog
/usr/share/doc/libmemcached-1.0.16/README
/usr/share/doc/libmemcached-1.0.16/THANKS
/usr/share/doc/libmemcached-1.0.16/TODO
/usr/share/man/man1/memaslap.1.gz
/usr/share/man/man1/memcapable.1.gz
/usr/share/man/man1/memcat.1.gz
/usr/share/man/man1/memcp.1.gz
/usr/share/man/man1/memdump.1.gz
/usr/share/man/man1/memerror.1.gz
/usr/share/man/man1/memexist.1.gz
/usr/share/man/man1/memflush.1.gz
/usr/share/man/man1/memparse.1.gz
/usr/share/man/man1/memping.1.gz
/usr/share/man/man1/memrm.1.gz
/usr/share/man/man1/memslap.1.gz
/usr/share/man/man1/memstat.1.gz
/usr/share/man/man1/memtouch.1.gz

#测试memcached是否可用
[root@c7-memcached-61 memcached-1.6.23]# memping --servers=127.0.0.1
[root@c7-memcached-61 memcached-1.6.23]# echo $?
0

#查看memcached状态
[root@c7-memcached-61 memcached-1.6.23]# memstat --servers=127.0.0.1
Server: 127.0.0.1 (11211)
     pid: 4640
     uptime: 484
     time: 1707963027
     version: 1.6.23
     libevent: 2.0.21-stable
     pointer_size: 64
     rusage_user: 0.018724
     rusage_system: 0.037449
     max_connections: 1024
     curr_connections: 2
     total_connections: 4
     rejected_connections: 0
     connection_structures: 3
     response_obj_oom: 0
     response_obj_count: 1
     response_obj_bytes: 32768
     read_buf_count: 4
     read_buf_bytes: 65536
     read_buf_bytes_free: 16384
     read_buf_oom: 0
     reserved_fds: 20
     cmd_get: 0
     cmd_set: 0
     cmd_flush: 0
     cmd_touch: 0
     cmd_meta: 0
     get_hits: 0
     get_misses: 0
     get_expired: 0
     get_flushed: 0
     delete_misses: 0
     delete_hits: 0
     incr_misses: 0
     incr_hits: 0
     decr_misses: 0
     decr_hits: 0
     cas_misses: 0
     cas_hits: 0
     cas_badval: 0
     touch_hits: 0
     touch_misses: 0
     store_too_large: 0
     store_no_memory: 0
     auth_cmds: 0
     auth_errors: 0
     bytes_read: 32
     bytes_written: 32
     limit_maxbytes: 67108864
     accepting_conns: 1
     listen_disabled_num: 0
     time_in_listen_disabled_us: 0
     threads: 4
     conn_yields: 0
     hash_power_level: 16
     hash_bytes: 524288
     hash_is_expanding: 0
     slab_reassign_rescues: 0
     slab_reassign_chunk_rescues: 0
     slab_reassign_evictions_nomem: 0
     slab_reassign_inline_reclaim: 0
     slab_reassign_busy_items: 0
     slab_reassign_busy_deletes: 0
     slab_reassign_running: 0
     slabs_moved: 0
     lru_crawler_running: 0
     lru_crawler_starts: 4
     lru_maintainer_juggles: 533
     malloc_fails: 0
     log_worker_dropped: 0
     log_worker_written: 0
     log_watcher_skipped: 0
     log_watcher_sent: 0
     log_watchers: 0
     unexpected_napi_ids: 0
     round_robin_fallback: 0
     bytes: 0
     curr_items: 0
     total_items: 0
     slab_global_page_pool: 0
     expired_unfetched: 0
     evicted_unfetched: 0
     evicted_active: 0
     evictions: 0
     reclaimed: 0
     crawler_reclaimed: 0
     crawler_items_checked: 0
     lrutail_reflocked: 0
     moves_to_cold: 0
     moves_to_warm: 0
     moves_within_lru: 0
     direct_reclaims: 0
     lru_bumps_dropped: 0

4、memcached 操作命令

五种基本 memcached 命令执行最简单的操作。这些命令和操作包括:
set
add
replace
get
delete
#前三个命令是用于操作存储在 memcached 中的键值对的标准修改命令,都使用如下所示的语法:
command <key> <flags> <expiration time> <bytes> <value>

#参数说明如下:
command set/add/replace
key     key 用于查找缓存值
flags     可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息
expiration time     在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)
bytes     在缓存中存储的字节数
value     存储的值(始终位于第二行)

#增加key,过期时间为秒,bytes为存储数据的字节数
add key flags exptime bytes 
[root@c7-memcached-61 memcached-1.6.23]# yum -y install telnet

[root@c7-memcached-61 memcached-1.6.23]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.

[root@c7-memcached-61 memcached-1.6.23]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
stats
STAT pid 4640
STAT uptime 895
STAT time 1707963438
STAT version 1.6.23
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.032486
STAT rusage_system 0.064972
STAT max_connections 1024
STAT curr_connections 2
STAT total_connections 5
STAT rejected_connections 0
STAT connection_structures 3
STAT response_obj_oom 0
STAT response_obj_count 1
STAT response_obj_bytes 49152
STAT read_buf_count 6
STAT read_buf_bytes 98304
STAT read_buf_bytes_free 32768
STAT read_buf_oom 0
STAT reserved_fds 20
STAT cmd_get 0
STAT cmd_set 0
STAT cmd_flush 0
STAT cmd_touch 0
STAT cmd_meta 0
STAT get_hits 0
STAT get_misses 0
STAT get_expired 0
STAT get_flushed 0
STAT delete_misses 0
STAT delete_hits 0
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT store_too_large 0
STAT store_no_memory 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 45
STAT bytes_written 2244
STAT limit_maxbytes 67108864
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT time_in_listen_disabled_us 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT slab_reassign_rescues 0
STAT slab_reassign_chunk_rescues 0
STAT slab_reassign_evictions_nomem 0
STAT slab_reassign_inline_reclaim 0
STAT slab_reassign_busy_items 0
STAT slab_reassign_busy_deletes 0
STAT slab_reassign_running 0
STAT slabs_moved 0
STAT lru_crawler_running 0
STAT lru_crawler_starts 5
STAT lru_maintainer_juggles 945
STAT malloc_fails 0
STAT log_worker_dropped 0
STAT log_worker_written 0
STAT log_watcher_skipped 0
STAT log_watcher_sent 0
STAT log_watchers 0
STAT unexpected_napi_ids 0
STAT round_robin_fallback 0
STAT bytes 0
STAT curr_items 0
STAT total_items 0
STAT slab_global_page_pool 0
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evicted_active 0
STAT evictions 0
STAT reclaimed 0
STAT crawler_reclaimed 0
STAT crawler_items_checked 0
STAT lrutail_reflocked 0
STAT moves_to_cold 0
STAT moves_to_warm 0
STAT moves_within_lru 0
STAT direct_reclaims 0
STAT lru_bumps_dropped 0
END

[root@c7-memcached-61 memcached-1.6.23]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
quit
Connection closed by foreign host.
[root@c7-memcached-61 memcached-1.6.23]#

[root@c7-memcached-61 memcached-1.6.23]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
add mykey 1 60 4
test
STORED

[root@c7-memcached-61 memcached-1.6.23]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
get mykey
VALUE mykey 1 4
test
END

[root@c7-memcached-61 memcached-1.6.23]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
set mykey 1 60 5
test1
STORED
get mykey
VALUE mykey 1 5
test1
END

[root@c7-memcached-61 memcached-1.6.23]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
delete mykey
DELETED
get mykey
END

清除

[root@c7-memcached-61 memcached-1.6.23]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
flush_all
OK


九、Session 共享服务器

1、MSM 介绍

MSM(memcached session manager)提供将Tomcat的session保持到memcached或Redis的程序, 可以实现高可用。


2、安装

参考链接: https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration

将spymemcached.jar、memcached-session-manage、kyro相关的jar文件都放到Tomcat的lib目录中 去,这个目录是 $CATALINA_HOME/lib/ ,对应本次安装就是/usr/local/tomcat/lib。


3、Sticky 模式

1.Sticky 模式工作原理

sticky 模式即前端tomcat和后端memcached有关联(粘性)关系

t1和m1部署可以在一台主机上,t2和m2部署也可以在同一台。

当新用户发请求到Tomcat1时, Tomcat1生成session返回给用户的同时,也会同时发给memcached2备 份。即Tomcat1 session为主session,memcached2 session为备用session,使用memcached相当 于备份了一份Session

如果Tomcat1发现memcached2 失败,无法备份Session到memcached2,则将Sessoin备份存放在 memcached1中


2.配置过程

Sticky准备规划

IP 主机名 服务 软件
172.29.7.31 c7-nginx-master-31 proxy Nginx
172.29.7.51 c7-tomcat-master-51 tomcat1 Tomcat、memcached
172.29.7.52 c7-tomcat-slave-52 tomcat2 Tomcat、memcached

配置 Nginx 充当 Proxy

upstream tomcat-server {
        #ip_hash;         # 先禁用看看轮询,之后开启开黏性,只根据客户端IP的前三位十进制数字
        #hash $remote_addr consistent;       # 根据客户端IP的全部位
        #hash $cookie_JSESSIONID consistent; # 先禁用看看轮询,之后开启开黏性,JSESSIONID可以小写
        server 172.29.7.51:8080;
        server 172.29.7.52:8080;
    }

    server {
        listen       80;
        server_name  www.jiutingqiu.com;

        location / {
                #proxy_set_header Host $http_host; #转发主机头至后端服务器
        }
        #return 302 https://$host$request_uri;

        location ~* \.(jsp|do)$ {
                proxy_pass http://tomcat-server;
        }

[root@c7-nginx-master-31 ~]# nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@c7-nginx-master-31 ~]# nginx -s reload

配置 Memcached

c7-tomcat-master-51

[root@c7-tomcat-master-51 ~]# yum -y install memcached
[root@c7-tomcat-master-51 ~]# cat /etc/sysconfig/memcached 
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
#注释下面这一行
#OPTIONS=""

[root@c7-tomcat-master-51 ~]# systemctl enable --now memcached.service 
Created symlink from /etc/systemd/system/multi-user.target.wants/memcached.service to /usr/lib/systemd/system/memcached.service.

c7-tomcat-slave-52
和tomcat1一样的过程

[root@c7-tomcat-slave-52 ~]# yum -y install memcached
[root@c7-tomcat-slave-52 ~]# cat /etc/sysconfig/memcached 
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
#OPTIONS=""

[root@c7-tomcat-slave-52 ~]# systemctl enable --now memcached.service 
Created symlink from /etc/systemd/system/multi-user.target.wants/memcached.service to /usr/lib/systemd/system/memcached.service.

配置Tomcat

c7-tomcat-master-51

[root@c7-tomcat-master-51 ~]# cat /usr/local/tomcat/conf/server.xml 

<Host name="localhost"  appBase="/data/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 "%r" %s %b" />

      </Host>

[root@c7-tomcat-master-51 ~]# mkdir -p /data/webapps/ROOT
[root@c7-tomcat-master-51 ~]# cp -r /usr/local/tomcat/webapps/ROOT/* /data/webapps/ROOT/
[root@c7-tomcat-master-51 ~]# echo > /data/webapps/ROOT/index.jsp 

[root@c7-tomcat-master-51 ~]# cat /data/webapps/ROOT/index.jsp 
<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>tomcat test</title>
</head>
<body>
<h1> tomcat website </h1>
<div>On <%=request.getServerName() %></div>
<div><%=request.getLocalAddr() + ":" + request.getLocalPort() %></div>
<div>SessionID = <span style="color:blue"><%=session.getId() %></span></div>
<%=new Date()%>
</body>
</html>

[root@c7-tomcat-master-51 ~]# chown -R tomcat:tomcat  /data
[root@c7-tomcat-master-51 ~]# systemctl restart tomcat
[root@c7-tomcat-master-51 ~]# cat /usr/local/tomcat/conf/context.xml 

    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
        memcachedNodes="n1:1172.29.7.51:11211,n2:172.29.7.52:11211"                     

        failoverNodes="n1"
        requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
        transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    />
</Context>
[root@c7-tomcat-master-51 ~]# cd /usr/local/tomcat/lib/

#下载相关jar包,参考下面官方说明的下载链接
#https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration
#将相关包传到lib/目录下,共10个文件
asm-5.2.jar
kryo-3.0.3.jar
kryo-serializers-0.45.jar
memcached-session-manager-2.3.2.jar
memcached-session-manager-tc8-2.3.2.jar
minlog-1.3.1.jar
msm-kryo-serializer-2.3.2.jar
objenesis-2.6.jar
reflectasm-1.11.9.jar
spymemcached-2.12.3.jar

[root@c7-tomcat-master-51 lib]# ls -1
annotations-api.jar
asm-5.2.jar
catalina-ant.jar
catalina-ha.jar
catalina.jar
catalina-ssi.jar
catalina-storeconfig.jar
catalina-tribes.jar
ecj-4.20.jar
el-api.jar
jasper-el.jar
jasper.jar
jaspic-api.jar
jedis-3.0.0.jar
jsp-api.jar
kryo-3.0.3.jar
kryo-serializers-0.45.jar
memcached-session-manager-2.3.2.jar
memcached-session-manager-tc9-2.3.2.jar
minlog-1.3.1.jar
msm-kryo-serializer-2.3.2.jar
objenesis-2.6.jar
reflectasm-1.11.9.jar
servlet-api.jar
spymemcached-2.12.3.jar
tomcat-api.jar
tomcat-coyote.jar
tomcat-dbcp.jar
tomcat-i18n-cs.jar
tomcat-i18n-de.jar
tomcat-i18n-es.jar
tomcat-i18n-fr.jar
tomcat-i18n-ja.jar
tomcat-i18n-ko.jar
tomcat-i18n-pt-BR.jar
tomcat-i18n-ru.jar
tomcat-i18n-zh-CN.jar
tomcat-jdbc.jar
tomcat-jni.jar
tomcat-util.jar
tomcat-util-scan.jar
tomcat-websocket.jar
websocket-api.jar

[root@c7-tomcat-master-51 lib]# systemctl restart tomcat
[root@c7-tomcat-master-51 lib]# systemctl status tomcat
● tomcat.service - Tomcat
   Loaded: loaded (/usr/lib/systemd/system/tomcat.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2024-02-15 11:37:57 CST; 4s ago
  Process: 2741 ExecStop=/usr/local/tomcat/bin/shutdown.sh (code=exited, status=0/SUCCESS)
  Process: 2774 ExecStart=/usr/local/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 2782 (java)
    Tasks: 18
   CGroup: /system.slice/tomcat.service
           └─2782 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.Cl...

Feb 15 11:37:57 c7-tomcat-master-51 systemd[1]: Starting Tomcat...
Feb 15 11:37:57 c7-tomcat-master-51 systemd[1]: Started Tomcat.

c7-tomcat-slave-52
配置也相同

[root@c7-tomcat-slave-52 ~]# cat /usr/local/tomcat/conf/server.xml 

<Host name="localhost"  appBase="/data/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 "%r" %s %b" />

      </Host>

[root@c7-tomcat-slave-52 ~]# mkdir -p /data/webapps/ROOT
[root@c7-tomcat-slave-52 ~]# cp -r /usr/local/tomcat/webapps/ROOT/* /data/webapps/ROOT/
[root@c7-tomcat-slave-52 ~]# echo > /data/webapps/ROOT/index.jsp 

[root@c7-tomcat-slave-52 ~]# cat /data/webapps/ROOT/index.jsp 
<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>tomcat test</title>
</head>
<body>
<h1> tomcat website </h1>
<div>On <%=request.getServerName() %></div>
<div><%=request.getLocalAddr() + ":" + request.getLocalPort() %></div>
<div>SessionID = <span style="color:blue"><%=session.getId() %></span></div>
<%=new Date()%>
</body>
</html>

[root@c7-tomcat-slave-52 ~]# chown -R tomcat:tomcat  /data
[root@c7-tomcat-slave-52 ~]# systemctl restart tomcat
[root@c7-tomcat-slave-52 ~]# cat /usr/local/tomcat/conf/context.xml 

    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
        memcachedNodes="n1:1172.29.7.51:11211,n2:172.29.7.52:11211"                     

        failoverNodes="n1"
        requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
        transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    />
</Context>
[root@c7-tomcat-slave-52 ~]# cd /usr/local/tomcat/lib/

#下载相关jar包,参考下面官方说明的下载链接
#https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration
#将相关包传到lib/目录下,共10个文件
asm-5.2.jar
kryo-3.0.3.jar
kryo-serializers-0.45.jar
memcached-session-manager-2.3.2.jar
memcached-session-manager-tc8-2.3.2.jar
minlog-1.3.1.jar
msm-kryo-serializer-2.3.2.jar
objenesis-2.6.jar
reflectasm-1.11.9.jar
spymemcached-2.12.3.jar

[root@c7-tomcat-slave-52 lib]# ls -1
annotations-api.jar
asm-5.2.jar
catalina-ant.jar
catalina-ha.jar
catalina.jar
catalina-ssi.jar
catalina-storeconfig.jar
catalina-tribes.jar
ecj-4.20.jar
el-api.jar
jasper-el.jar
jasper.jar
jaspic-api.jar
jedis-3.0.0.jar
jsp-api.jar
kryo-3.0.3.jar
kryo-serializers-0.45.jar
memcached-session-manager-2.3.2.jar
memcached-session-manager-tc9-2.3.2.jar
minlog-1.3.1.jar
msm-kryo-serializer-2.3.2.jar
objenesis-2.6.jar
reflectasm-1.11.9.jar
servlet-api.jar
spymemcached-2.12.3.jar
tomcat-api.jar
tomcat-coyote.jar
tomcat-dbcp.jar
tomcat-i18n-cs.jar
tomcat-i18n-de.jar
tomcat-i18n-es.jar
tomcat-i18n-fr.jar
tomcat-i18n-ja.jar
tomcat-i18n-ko.jar
tomcat-i18n-pt-BR.jar
tomcat-i18n-ru.jar
tomcat-i18n-zh-CN.jar
tomcat-jdbc.jar
tomcat-jni.jar
tomcat-util.jar
tomcat-util-scan.jar
tomcat-websocket.jar
websocket-api.jar

[root@c7-tomcat-slave-52 lib]# systemctl restart tomcat
[root@c7-tomcat-slave-52 lib]# systemctl status tomcat
● tomcat.service - Tomcat
   Loaded: loaded (/usr/lib/systemd/system/tomcat.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2024-02-15 11:37:57 CST; 4s ago
  Process: 2741 ExecStop=/usr/local/tomcat/bin/shutdown.sh (code=exited, status=0/SUCCESS)
  Process: 2774 ExecStart=/usr/local/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 2782 (java)
    Tasks: 18
   CGroup: /system.slice/tomcat.service
           └─2782 /usr/local/jdk/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.Cl...

Feb 15 11:37:57 c7-tomcat-slave-52 systemd[1]: Starting Tomcat...
Feb 15 11:37:57 c7-tomcat-slave-52 systemd[1]: Started Tomcat.

查看Tomcat日志

[root@c7-tomcat-master-51 ~]# tail -n 20 /usr/local/tomcat/logs/catalina.out 
15-Feb-2024 12:09:59.209 INFO [main] de.javakaffee.web.msm.MemcachedSessionService.startInternal  starts initialization... (configured nodes definition n1:172.29.7.51:11211,n2:172.29.7.52:11211, failover nodes n1)
2024-02-15 12:09:59.236 INFO net.spy.memcached.MemcachedConnection:  Setting retryQueueSize to -1
2024-02-15 12:09:59.239 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/172.29.7.51:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
2024-02-15 12:09:59.240 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/172.29.7.52:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
15-Feb-2024 12:09:59.242 INFO [main] de.javakaffee.web.msm.RequestTrackingHostValve.<init> Setting ignorePattern to .*\.(ico|png|gif|jpg|css|js)$
15-Feb-2024 12:09:59.248 INFO [main] de.javakaffee.web.msm.MemcachedSessionService.setLockingMode Setting lockingMode to null
15-Feb-2024 12:09:59.251 INFO [main] de.javakaffee.web.msm.MemcachedSessionService.createTranscoderFactory Creating transcoder factory de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory
15-Feb-2024 12:09:59.255 INFO [main] de.javakaffee.web.msm.serializer.kryo.KryoTranscoder.<init> Starting with initialBufferSize 102400, maxBufferSize 2048000 and defaultSerializerFactory de.javakaffee.web.msm.serializer.kryo.DefaultFieldSerializerFactory
15-Feb-2024 12:09:59.259 INFO [main] de.javakaffee.web.msm.MemcachedSessionService.startInternal --------
-  finished initialization:
- sticky: true
- operation timeout: 1000
- node ids: [n2]
- failover node ids: [n1]
- storage key prefix: null
- locking mode: null (expiration: 5s)
--------
15-Feb-2024 12:09:59.272 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/data/webapps/ROOT] has finished in [342] ms
15-Feb-2024 12:09:59.274 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
15-Feb-2024 12:09:59.282 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [379] milliseconds

4、Non-Sticky 模式

1.Non-Sticky 模式工作原理

non-sticky 模式即前端tomcat和后端memcached无关联(无粘性)关系

Tomcat session为中转Session,对每一个SessionID随机选中后端的memcached节点n1(或者n2)为主 session,而另一个memcached节点n2(或者是n1)为备session。产生的新的Session会发送给主、备 memcached,并清除本地Session。

后端两个memcached服务器对一个session来说是一个是主,一个是备,但对所有session信息来说每个 memcached即是主同时也是备

如果n1下线,n2则转正。n1再次上线,n2依然是主Session存储节点。


2.配置过程

Non-Sticky 准备规划

IP 主机名 服务 软件
172.29.7.31 c7-nginx-master-31 proxy Nginx
172.29.7.51 c7-tomcat-master-51 tomcat1 Tomcat、memcached
172.29.7.52 c7-tomcat-slave-52 tomcat2 Tomcat、memcached

Memcached 配置

c7-tomcat-master-51

[root@c7-tomcat-master-51 ~]# cat /usr/local/tomcat/conf/context.xml 

    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
        memcachedNodes="n1:1172.29.7.51:11211,n2:172.29.7.52:11211" 
        #新加这三行
        sticky="false"
        sessionBackupAsync="false"
        lockingMode="uriPattern:/path1|/path2"    
        requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
        transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    />
</Context>

#查看日志
[root@c7-tomcat-master-51 ~]# tail -n 20 /usr/local/tomcat/logs/catalina.out
15-Feb-2024 12:42:19.861 INFO [main] de.javakaffee.web.msm.MemcachedSessionService.startInternal --------
-  finished initialization:
- sticky: false
- operation timeout: 1000
- node ids: [n1, n2]
- failover node ids: []
- storage key prefix: null
- locking mode: uriPattern:/path1|/path2 (expiration: 5s)

c7-tomcat-slave-52
操作相同

[root@c7-tomcat-slave-52 ~]# cat /usr/local/tomcat/conf/context.xml 

    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
    <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
        memcachedNodes="n1:1172.29.7.51:11211,n2:172.29.7.52:11211" 
        #新加这三行
        sticky="false"
        sessionBackupAsync="false"
        lockingMode="uriPattern:/path1|/path2"    
        requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
        transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    />
</Context>


十、Tomcat优化

在目前流行的互联网架构中,Tomcat 在目前的网络编程中是举足轻重的,由于Tomcat的运行依赖于 JVM,从虚拟机的角度把Tomcat的调整分为外部环境调优 JVM 和 Tomcat 自身调优两部分

1、JVM 组成

[root@c7-tomcat-master-51 ~]# java -version
openjdk version "1.8.0_262"
OpenJDK Runtime Environment (build 1.8.0_262-b10)   #运行环境
OpenJDK 64-Bit Server VM (build 25.262-b10, mixed mode) #JVM

1.JVM 组成部分

类加载子系统: 使用Java语言编写.java Source Code文件,通过javac编译成.class Byte Code文件。class loader类加载器将所需所有类加载到内存,必要时将类实例化成实例

运行时数据区: 最消耗内存的空间,需要优化

执行引擎: 包括JIT (JustInTimeCompiler)即时编译器, GC垃圾回收器

本地方法接口: 将本地方法栈通过JNI(Java Native Interface)调用Native Method Libraries, 比如:C,C++库等,扩展Java功能,融合不同的编程语言为Java所用

2.虚拟机

目前HotSpot是最主要的 JVM。
安卓程序需要运行在JVM上,而安卓平台使用了Google自研的Java虚拟机——Dalvid,适合于内存、处理器能力有限系统。

3.垃圾收集器

在堆内存中如果创建的对象不再使用,仍占用着内存,此时即为垃圾.需要即使进行垃圾回收,从而释放内存空间给其它对象使用

4.jvm的相关工具

jps             查看所有jvm进程
jinfo           查看进程的运行环境参数,主要是jvm命令行参数
jstat           对jvm应用程序的资源和性能进行实时监控
jstack          查看所有线程的运行状态
jmap            查看jvm占用物理内存的状态
jhat            +UseParNew
jconsole        图形工具
jvisualvm       图形工具,jdk-8u361版后被取消

2、Tomcat优化常用配置

1.内存空间优化

JAVA_OPTS="-server -Xms4g -Xmx4g -XX:NewSize= -XX:MaxNewSize= "
-server:服务器模式
-Xms:堆内存初始化大小
-Xmx:堆内存空间上限
-XX:NewSize=:新生代空间初始化大小 
-XX:MaxNewSize=:新生代空间最大值

2.线程池调整

[root@c7-tomcat-master-51 ~]# vim /usr/local/tomcat/conf/server.xml
......
<Connector port="8080" protocol="HTTP/1.1"  connectionTimeout="20000"
redirectPort="8443"  maxThreads="2000"/>
......

常用属性:
connectionTimeout :连接超时时长,单位ms

maxThreads:最大线程数,默认200

minSpareThreads:最小空闲线程数

maxSpareThreads:最大空闲线程数

acceptCount:当启动线程满了之后,等待队列的最大长度,默认100

URIEncoding:URI 地址编码格式,建议使用 UTF-8

enableLookups:是否启用客户端主机名的DNS反向解析,缺省禁用,建议禁用,就使用客户端IP就行

compression:是否启用传输压缩机制,建议 "on",CPU和流量的平衡

compressionMinSize:启用压缩传输的数据流最小值,单位是字节

compressableMimeType:定义启用压缩功能的MIME类型text/html, text/xml, text/css, text/javascript

Related Post

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注