目录
一、实验环境搭建
二、部署Nginx代理服务器配置
三、部署后端真是服务器Tomcat配置
四、配置Tomcat的Session ID会话保持
五、测试
此次实验是Tomcat后端服务器如何做Session ID会话保持
一、实验环境搭建
[root@localhost ~]#systemctl stop firewalld
[root@localhost ~]#setenforce 0
setenforce: SELinux is disabled
[root@localhost ~]#yum install epel-release.noarch -y
#安装epel额外源
[root@localhost ~]#yum install nginx -y
#yum安装Nginx 作为代理服务器
[root@localhost ~]#systemctl start nginx
[root@localhost ~]#systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
Active: active (running) since 六 2024-03-16 10:21:23 CST; 5s ago
Process: 2055 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
Process: 2051 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
Process: 2049 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
Main PID: 2058 (nginx)
CGroup: /system.slice/nginx.service
├─2058 nginx: master process /usr/sbin/nginx
├─2059 nginx: worker process
└─2060 nginx: worker process
3月 16 10:21:23 localhost.localdomain systemd[1]: Starting The nginx HTTP ...
3月 16 10:21:23 localhost.localdomain nginx[2051]: nginx: the configuratio...
3月 16 10:21:23 localhost.localdomain nginx[2051]: nginx: configuration fi...
3月 16 10:21:23 localhost.localdomain systemd[1]: Started The nginx HTTP a...
Hint: Some lines were ellipsized, use -l to show in full.
[root@node2 ~]#systemctl stop firewalld
[root@node2 ~]#setenforce 0
[root@node2 ~]#rz -E
rz waiting to receive.
[root@node2 ~]#rz -E
rz waiting to receive.
[root@node2 ~]#ls
anaconda-ks.cfg Downloads Pictures
apache-tomcat-9.0.16.tar.gz initial-setup-ks.cfg Public
Desktop jdk-8u291-linux-x64.tar.gz Templates
Documents Music Videos
[root@node2 ~]#tar xf jdk-8u291-linux-x64.tar.gz -C /usr/local/
[root@node2 ~]#cd /usr/local/
[root@node2 local]#ls
bin etc games include jdk1.8.0_291 lib lib64 libexec sbin share src
[root@node2 local]#ln -s jdk1.8.0_291/ jdk
[root@node2 local]#vim /etc/profile.d/jdk.sh
[root@node2 local]#cat /etc/profile.d/jdk.sh
export JAVA_HOME=/usr/local/jdk
export CLASSPATH=$JAVA_HOME/lib/:$JRE_HOME/lib/
export PATH=$JAVA_HOME/bin:$PATH
export JRE_HOME=$JAVA_HOME/jre
[root@node2 local]#. /etc/profile.d/jdk.sh
[root@node2 local]#java -version
java version "1.8.0_291"
Java(TM) SE Runtime Environment (build 1.8.0_291-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.291-b10, mixed mode)
[root@node3 ~]#systemctl stop firewalld
[root@node3 ~]#setenforce 0
[root@node3 ~]#rz -E
rz waiting to receive.
[root@node3 ~]#rz -E
rz waiting to receive.
[root@node3 ~]#ls
anaconda-ks.cfg jdk-8u291-linux-x64.tar.gz 视频 下载
apache-tomcat-9.0.16.tar.gz 公共 图片 音乐
initial-setup-ks.cfg 模板 文档 桌面
[root@node3 ~]#tar xf jdk-8u291-linux-x64.tar.gz -C /usr/local/
[root@node3 ~]#cd /usr/local/
[root@node3 local]#ls
bin etc games include jdk1.8.0_291 lib lib64 libexec sbin share src
[root@node3 local]#ln -s jdk1.8.0_291/ jdk
[root@node3 local]#vim /etc/profile.d/jdk.sh
[root@node3 local]#cat /etc/profile.d/jdk.sh
export JAVA_HOME=/usr/local/jdk
export CLASSPATH=$JAVA_HOME/lib/:$JRE_HOME/lib/
export PATH=$JAVA_HOME/bin:$PATH
export JRE_HOME=$JAVA_HOME/jre
[root@node3 local]#. /etc/profile.d/jdk.sh
[root@node3 local]#java -version
java version "1.8.0_291"
Java(TM) SE Runtime Environment (build 1.8.0_291-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.291-b10, mixed mode)
二、部署Nginx代理服务器配置
[root@localhost ~]#vim /etc/nginx/nginx.conf
[root@localhost ~]#sed -n '23,26p' /etc/nginx/nginx.conf
upstream tomcat {
server 192.168.241.22:8080;
server 192.168.241.23:8080;
}
[root@localhost ~]#sed -n '50,52p' /etc/nginx/nginx.conf
location ~* \.jsp$ {
proxy_pass http://tomcat;
}
[root@localhost ~]#nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@localhost ~]#nginx -s reload
三、部署后端真是服务器Tomcat配置
[root@node2 local]#cd
[root@node2 ~]#ls
anaconda-ks.cfg Downloads Pictures
apache-tomcat-9.0.16.tar.gz initial-setup-ks.cfg Public
Desktop jdk-8u291-linux-x64.tar.gz Templates
Documents Music Videos
[root@node2 ~]#tar xf apache-tomcat-9.0.16.tar.gz -C /usr/local/
[root@node2 ~]#cd /usr/local/
[root@node2 local]#ls
apache-tomcat-9.0.16 etc include jdk1.8.0_291 lib64 sbin src
bin games jdk lib libexec share
[root@node2 local]#ln -s apache-tomcat-9.0.16/ tomcat
[root@node2 local]#ls
apache-tomcat-9.0.16 etc include jdk1.8.0_291 lib64 sbin src
bin games jdk lib libexec share tomcat
[root@node2 local]#cd tomcat/
[root@node2 tomcat]#useradd -s /sbin/nologin tomcat
[root@node2 tomcat]#chown tomcat:tomcat tomcat/ -R
chown: cannot access ‘tomcat/’: No such file or directory
[root@node2 tomcat]#chown tomcat:tomcat -R
chown: missing operand after ‘tomcat:tomcat’
Try 'chown --help' for more information.
[root@node2 tomcat]#cd ..
[root@node2 local]#chown tomcat:tomcat tomcat/ -R
[root@node2 local]#cat > /usr/lib/systemd/system/tomcat.service <<EOF
> [Unit]
> Description=Tomcat
> After=syslog.target network.target
>
> [Service]
> Type=forking
> ExecStart=/usr/local/tomcat/bin/startup.sh
> ExecStop=/usr/local/tomcat/bin/shutdown.sh
> RestartSec=3
> PrivateTmp=true
> User=tomcat
> Group=tomcat
>
> [Install]
> WantedBy=multi-user.target
>
> EOF
[root@node2 local]#cd tomcat/webapps/ROOT/
[root@node2 ROOT]#ls
asf-logo-wide.svg bg-upper.png tomcat.css tomcat.svg
bg-button.png favicon.ico tomcat.gif WEB-INF
bg-middle.png index.jsp tomcat.png
bg-nav.png RELEASE-NOTES.txt tomcat-power.gif
[root@node2 ROOT]#mv index.jsp index.jsp.bak
[root@node2 ROOT]#rz -E
rz waiting to receive.
[root@node2 ROOT]#ls
asf-logo-wide.svg bg-upper.png RELEASE-NOTES.txt tomcat-power.gif
bg-button.png favicon.ico tomcat.css tomcat.svg
bg-middle.png index.jsp tomcat.gif WEB-INF
bg-nav.png index.jsp.bak tomcat.png
[root@node2 ROOT]#cat index.jsp
<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tomcat test</title>
</head>
<body>
<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@node2 ROOT]#systemctl start tomcat
[root@node3 local]#cd
[root@node3 ~]#ls
anaconda-ks.cfg jdk-8u291-linux-x64.tar.gz 视频 下载
apache-tomcat-9.0.16.tar.gz 公共 图片 音乐
initial-setup-ks.cfg 模板 文档 桌面
[root@node3 ~]#tar xf apache-tomcat-9.0.16.tar.gz -C /usr/local/
[root@node3 ~]#cd /usr/local/
[root@node3 local]#ls
apache-tomcat-9.0.16 etc include jdk1.8.0_291 lib64 sbin src
bin games jdk lib libexec share
[root@node3 local]#ln -s apache-tomcat-9.0.16/ tomcat
[root@node3 local]#ls
apache-tomcat-9.0.16 etc include jdk1.8.0_291 lib64 sbin src
bin games jdk lib libexec share tomcat
[root@node3 local]#cd tomcat/
[root@node3 tomcat]#useradd -s /sbin/nologin tomcat
[root@node3 tomcat]#chown tomcat:tomcat tomcat/ -R
chown: 无法访问"tomcat/": 没有那个文件或目录
[root@node3 tomcat]#chown tomcat:tomcat -R
chown: "tomcat:tomcat" 后缺少操作数
Try 'chown --help' for more information.
[root@node3 tomcat]#cd ..
[root@node3 local]#chown tomcat:tomcat tomcat/ -R
[root@node3 local]#cat > /usr/lib/systemd/system/tomcat.service <<EOF
> [Unit]
> Description=Tomcat
> After=syslog.target network.target
>
> [Service]
> Type=forking
> ExecStart=/usr/local/tomcat/bin/startup.sh
> ExecStop=/usr/local/tomcat/bin/shutdown.sh
> RestartSec=3
> PrivateTmp=true
> User=tomcat
> Group=tomcat
>
> [Install]
> WantedBy=multi-user.target
>
> EOF
[root@node3 local]#cd tomcat/webapps/ROOT/
[root@node3 ROOT]#ls
asf-logo-wide.svg bg-upper.png tomcat.css tomcat.svg
bg-button.png favicon.ico tomcat.gif WEB-INF
bg-middle.png index.jsp tomcat.png
bg-nav.png RELEASE-NOTES.txt tomcat-power.gif
[root@node3 ROOT]#mv index.jsp index.jsp.bak
[root@node3 ROOT]#rz -E
rz waiting to receive.
[root@node3 ROOT]#cat index.jsp
<%@ page import="java.util.*" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tomcat test</title>
</head>
<body>
<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@node3 ROOT]#systemctl start tomcat
实际生产环境不允许Session ID不断变动的。
- 客户第一次访问被调度到后端真实服务器Tomcat1上,由于是第一次访问,客户度的Cookie缓存会记录,不会有SessionID,Tomcat1服务器会生成新的Session ID传输给客户端,客户端会将这个新的Session ID记录下来;
- 当第二次访问的时候,Nginx代理服务器又可能将服务请求调度到后端真实服务器Tomcat2上,Tomcat2服务器是没有客户端传输来的Session ID1的,Tomcat2服务器认为客户端要生成新的SessionID,于是Tomcat2服务器将新的Session ID2传输给客户端,客户端会更新Session ID,将刚刚的SessionID更改为SessionID2;
- 当第三次访问的时候,客户端带着SessionID2去Nginx代理服务器,Nginx代理服务器可能将客户端又调度到Tomcat1服务器上,Tomcat1服务器并没有SessionID2,于是又将新生成的SessionID3传输给客户端,这样会有很不好的客户端体验,所以我们可以根据修改Tomcat配置文件来进行会话保持
四、配置Tomcat的Session ID会话保持
Tomcat会话保持官方说明https://tomcat.apache.org/tomcat-9.0-doc/cluster-howto.html
[root@node2 ROOT]#vim /usr/local/tomcat/conf/server.xml
[root@node2 ROOT]#sed -n '163,201p' /usr/local/tomcat/conf/server.xml
<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"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.241.22"
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>
[root@node3 ROOT]#vim /usr/local/tomcat/conf/server.xml
[root@node3 ROOT]#sed -n '163,201p' /usr/local/tomcat/conf/server.xml
<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"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.241.23"
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>
[root@node2 ROOT]#vim /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml
[root@node2 ROOT]#sed -n 29p /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml
<distributable/>
[root@node2 ROOT]#systemctl restart tomcat
[root@node2 ROOT]#systemctl status tomcat.service
● tomcat.service - Tomcat
Loaded: loaded (/usr/lib/systemd/system/tomcat.service; disabled; vendor preset: disabled)
Active: active (running) since Fri 2024-03-15 22:42:31 EDT; 5s ago
Process: 2566 ExecStop=/usr/local/tomcat/bin/shutdown.sh (code=exited, status=0/SUCCESS)
Process: 2601 ExecStart=/usr/local/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
Main PID: 2617 (catalina.sh)
CGroup: /system.slice/tomcat.service
├─2617 /bin/sh /usr/local/tomcat/bin/catalina.sh start
└─2618 /usr/bin/java -Djava.util.logging.config.file=/usr/local/...
Mar 15 22:42:31 node2.localdomain systemd[1]: Starting Tomcat...
Mar 15 22:42:31 node2.localdomain systemd[1]: Started Tomcat.
[root@node3 ROOT]#vim /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml
[root@node3 ROOT]#sed -n 29p /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml
<distributable/>
[root@node3 ROOT]#systemctl restart tomcat
[root@node3 ROOT]#systemctl status tomcat.service
● tomcat.service - Tomcat
Loaded: loaded (/usr/lib/systemd/system/tomcat.service; disabled; vendor preset: disabled)
Active: active (running) since 六 2024-03-16 18:42:30 CST; 5s ago
Process: 2480 ExecStop=/usr/local/tomcat/bin/shutdown.sh (code=exited, status=0/SUCCESS)
Process: 2518 ExecStart=/usr/local/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
Main PID: 2533 (catalina.sh)
CGroup: /system.slice/tomcat.service
├─2533 /bin/sh /usr/local/tomcat/bin/catalina.sh start
└─2534 /usr/bin/java -Djava.util.logging.config.file=/usr/local/...
3月 16 18:42:30 node3.node3 systemd[1]: Starting Tomcat...
3月 16 18:42:30 node3.node3 startup.sh[2518]: Using CATALINA_BASE: /usr...t
3月 16 18:42:30 node3.node3 startup.sh[2518]: Using CATALINA_HOME: /usr...t
3月 16 18:42:30 node3.node3 startup.sh[2518]: Using CATALINA_TMPDIR: /usr...p
3月 16 18:42:30 node3.node3 startup.sh[2518]: Using JRE_HOME: /usr
3月 16 18:42:30 node3.node3 startup.sh[2518]: Using CLASSPATH: /usr...r
3月 16 18:42:30 node3.node3 systemd[1]: Started Tomcat.
Hint: Some lines were ellipsized, use -l to show in full.
五、测试
此时后端真实服务器Tomcat调优完成,SessionID会话保持完成,客户端体验绝佳!