一、tomcat介绍
Tomcat 是由 Apache 软件基金会(Apache Software Foundation)开发的一款开源、轻量级的 Java Web 服务器,同时也是最常用的 Servlet 容器(Servlet Container)。它主要用于部署和运行基于 Java 的 Web 应用程序,是 Java EE(现 Jakarta EE)生态中不可或缺的基础组件。
安装java
#安装java环境
[root@localhost ~]# dnf install java-1.8.0-openjdk.x86_64 -y
#查看java版本
[root@localhost ~]# 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)
[root@localhost ~]# which java
/usr/bin/java
[root@localhost ~]# ll /usr/bin/java
lrwxrwxrwx. 1 root root 22 7月 30 11:05 /usr/bin/java -> /etc/alternatives/java
[root@localhost ~]# cd /etc/alternatives/jre
[root@localhost jre]# ls
ASSEMBLY_EXCEPTION bin lib LICENSE THIRD_PARTY_README
安装tomcat
[root@localhost ~]# tar zxf apache-tomcat-9.0.107.tar.gz -C /usr/local/
[root@localhost ~]# cd /usr/local/
[root@localhost local]# ls
apache-tomcat-9.0.107 bin etc games include lib lib64 libexec sbin share src
[root@localhost local]# mv apache-tomcat-9.0.107/ tomcat
#启动tomcat
[root@localhost local]# cd tomcat/
[root@localhost tomcat]# cd bin/
[root@localhost bin]# ls
bootstrap.jar ciphers.sh daemon.sh setclasspath.bat startup.sh version.bat
catalina.bat commons-daemon.jar digest.bat setclasspath.sh tomcat-juli.jar version.sh
catalina.sh commons-daemon-native.tar.gz digest.sh shutdown.bat tomcat-native.tar.gz
catalina-tasks.xml configtest.bat makebase.bat shutdown.sh tool-wrapper.bat
ciphers.bat configtest.sh makebase.sh startup.bat tool-wrapper.sh
[root@localhost bin]# ./startup.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.
#查看端口
[root@localhost ~]# netstat -tlnp | grep java
tcp6 0 0 :::8080 :::* LISTEN 42487/java
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 42487/java
访问tomcat
生成tomcat的启动文件
172.25.254.10 172.25.254.11
#生成tomcat的主配置文件
[root@localhost bin]# vim /usr/local/tomcat/conf/tomcat.conf
JAVA_HOME=/etc/alternatives/jre
#生成启动文件
[root@localhost bin]# vim /lib/systemd/system/tomcat.service
[Unit]
Description=Tomcat
#After=syslog.target network.target remote-fs.target nss-lookup.target
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
生成tomcat用户并设定软件安装目录权限
[root@localhost bin]# useradd -s /sbin/nologin -M tomcat
[root@localhost bin]# chown tomcat.tomcat /usr/local/tomcat/ -R
开启tomcat
[root@localhost bin]# systemctl enable --now tomcat
Created symlink /etc/systemd/system/multi-user.target.wants/tomcat.service → /usr/lib/systemd/system/tomcat.service.
二、tomcat负载均衡实现
172.25.254.100
[root@localhost ~]# cd /etc/nginx/conf.d
[root@localhost conf.d]# ls
[root@localhost conf.d]# vim vhosts.conf
upstream tomcat{
hash $cookie_JSESSIONID;
server 172.25.254.10:8080;
server 172.25.254.11:8080;
}
server {
listen 80;
server_name www.wan.org;
location ~ \/jsp$ {
proxy_pass http://tomcat;
}
}
[root@localhost conf.d]# nginx -t
[root@localhost conf.d]# nginx -s reload
172.25.254.10 172.25.254.11
test.jsp
<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info:
<%
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<%
out.println("<br> ID " + session.getId()+"<br>");
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.print("<b>Session list</b>");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value+"<br>");
System.out.println( name + " = " + value);
}
%>
<form action="test.jsp" method="POST">
name:<input type=text size=20 name="dataName">
<br>
key:<input type=text size=20 name="dataValue">
<br>
<input type=submit>
</form>
</body>
</html>
172.25.254.100
负载均衡查看
三、Memcached
Memcached 是一款高性能的分布式内存对象缓存系统,提供了简单的键值对操作命令,用于快速存储和获取数据。
memcached的安装与启动
172.25.254.10 172.25.254.11
[root@localhost ~]# yum install memcached -y
[root@localhost ~]# vim /etc/sysconfig/memcache
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 0.0.0.0,::1"
[root@localhost ~]# systemctl enable --now memcached
Created symlink /etc/systemd/system/multi-user.target.wants/memcached.service → /usr/lib/systemd/system/memcached.service.
[root@localhost ~]# netstat -antlupe | grep memcache
tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 980 91087 46265/memcached
tcp6 0 0 ::1:11211 :::* LISTEN 980 91088 46265/memcached
memchahced 操作命令
set 无论键是否存在,都设置键值对。
get 获取键的值。
add 当键不存在时,添加键值对。
replace 当键存在时,更新键值对)。
delete 删除指定键。
[root@localhost ~]# telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
添加
add wankey 0 60 5 #0 是否压缩 60 过期时间 4 字长
admin
STORED
#查看
get wankey
VALUE wankey 0 5
admin
END
#修改
set wankey 0 60 4
admi
STORED
get wankey
VALUE wankey 0 4
admi
END
#删除
delete wankey
DELETED
get wankey
END
quit #退出
四、session 共享服务器
在分布式系统中,Tomcat 的 Session 共享是一个关键问题。当多个 Tomcat 实例组成集群提供服务时,用户的请求可能被分发到不同实例,若 Session 无法共享,会导致用户状态丢失(如登录失效)。
多台 Tomcat 服务器通过负载均衡(如 Nginx)协同工作,用户会话(Session)需在所有实例间同步。
172.25.254.10 172.25.254.11
[root@localhost ~]# ls
公共 模板 视频 图片 文档 下载 音乐 桌面 anaconda-ks.cfg apache-tomcat-9.0.107.tar.gz jar.zip
[root@localhost ~]# unzip jar.zip
Archive: jar.zip
creating: jar/
inflating: jar/asm-5.2.jar
inflating: jar/kryo-3.0.3.jar
inflating: jar/kryo-serializers-0.45.jar
inflating: jar/memcached-session-manager-2.3.2.jar
inflating: jar/memcached-session-manager-tc9-2.3.2.jar
inflating: jar/minlog-1.3.1.jar
inflating: jar/msm-kryo-serializer-2.3.2.jar
inflating: jar/objenesis-2.6.jar
inflating: jar/reflectasm-1.11.9.jar
inflating: jar/spymemcached-2.12.3.jar
[root@localhost ~]# cd jar/
[root@localhost jar]# ls
asm-5.2.jar memcached-session-manager-2.3.2.jar msm-kryo-serializer-2.3.2.jar spymemcached-2.12.3.jar
kryo-3.0.3.jar memcached-session-manager-tc9-2.3.2.jar objenesis-2.6.jar
kryo-serializers-0.45.jar minlog-1.3.1.jar reflectasm-1.11.9.jar
[root@localhost jar]# cp * /usr/local/tomcat/lib/
[root@localhost jar]# cd /usr/local/tomcat/lib/
[root@localhost lib]# ls
annotations-api.jar jasper.jar servlet-api.jar tomcat-i18n-ko.jar
asm-5.2.jar jaspic-api.jar spymemcached-2.12.3.jar tomcat-i18n-pt-BR.jar
catalina-ant.jar jsp-api.jar tomcat-api.jar tomcat-i18n-ru.jar
catalina-ha.jar kryo-3.0.3.jar tomcat-coyote-ffm.jar tomcat-i18n-zh-CN.jar
catalina.jar kryo-serializers-0.45.jar tomcat-coyote.jar tomcat-jdbc.jar
catalina-ssi.jar memcached-session-manager-2.3.2.jar tomcat-dbcp.jar tomcat-jni.jar
catalina-storeconfig.jar memcached-session-manager-tc9-2.3.2.jar tomcat-i18n-cs.jar tomcat-util.jar
catalina-tribes.jar minlog-1.3.1.jar tomcat-i18n-de.jar tomcat-util-scan.jar
ecj-4.20.jar msm-kryo-serializer-2.3.2.jar tomcat-i18n-es.jar tomcat-websocket.jar
el-api.jar objenesis-2.6.jar tomcat-i18n-fr.jar websocket-api.jar
jasper-el.jar reflectasm-1.11.9.jar tomcat-i18n-ja.jar
#172.25.254.10
[root@localhost lib]# vim /usr/local/tomcat/conf/context.xml
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:172.25.254.10:11211,n2:172.25.254.20:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
#172.25.254.11
[root@localhost lib]# vim /usr/local/tomcat/conf/context.xml
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:172.25.254.10:11211,n2:172.25.254.20:11211"
failoverNodes="n2"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
测试
172.25.254.100
1.在两台tomcat都开启的情况下: http://www.wan.org/test.jsp
2.在n1被停止后继续提交信息看是否可以读取到之前的会话信息