部署实验
开启三台虚拟机,一台充当nginx,两台tomcat
安装TOMCAT(在两套)
安装Java环境
bash
[root@localhost ~]# dnf install java-1.8.0-openjdk.x86_64 -y
[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)
#查看Java的环境目录
[root@localhost ~]# which java
/usr/bin/java
[root@localhost ~]# ll /usr/bin/java
lrwxrwxrwx 1 root root 22 Aug 11 18:48 /usr/bin/java -> /etc/alternatives/java
#Java的运行环境
[root@localhost ~]# cd /etc/alternatives/jre
[root@localhost jre]# ls
ASSEMBLY_EXCEPTION bin lib LICENSE THIRD_PARTY_README
安装tomcat
bash
#解压并重命名
[root@localhost ~]# tar zxf apache-tomcat-9.0.107.tar.gz -C /usr/local/
[root@localhost local]# mv apache-tomcat-9.0.107 tomcat
[root@localhost local]# ls
bin etc games include lib lib64 libexec sbin share src tomcat
#启动tomcat
[root@localhost tomcat]# cd bin/
[root@localhost bin]# ls
bootstrap.jar configtest.sh shutdown.sh
catalina.bat daemon.sh startup.bat
catalina.sh digest.bat startup.sh
catalina-tasks.xml digest.sh tomcat-juli.jar
ciphers.bat makebase.bat tomcat-native.tar.gz
ciphers.sh makebase.sh tool-wrapper.bat
commons-daemon.jar setclasspath.bat tool-wrapper.sh
commons-daemon-native.tar.gz setclasspath.sh version.bat
configtest.bat shutdown.bat version.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 bin]# netstat -antlupe | grep java
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 0 69644 36240/java
tcp6 0 0 :::8080 :::* LISTEN 0 69635 36240/java
访问成功

tomcat的文件结构组成
目录结构
目录 说明
bin 服务启动、停止等相关程序和文件
conf 配置文件
lib 库目录
logs 日志目录
webapps 应用程序,应用部署目录,相当于nginx的默认发布目录
work jsp 编译后的结果文件,建议提前预热访问
生成tomcat的启动文件(在两个tomcat主机下)
1、生成主配置文件
bash
[root@localhost ~]# vim /usr/local/tomcat/conf/tomcat.conf
JAVA_HOME=/etc/alternatives/jre
2、生成启动文件
bash
[root@localhost ~]# vim /lib/systemd/system/tomcat.service

3、生成用户并设定软件安装目录权限
bash
[root@localhost ~]# useradd -s /sbin/nologin -M tomcat
[root@localhost ~]# chown tomcat.tomcat /usr/local/tomcat/ -R
4、用启动脚本开启服务
bash
[root@localhost ~]# systemctl start tomcat
[root@localhost ~]# netstat -antlupe | grep java
tcp6 0 0 127.0.0.1:8005 :::* LISTEN 1000 76297 40054/java
nginx结合反向代理实现tomcat集群
常见部署方式介绍

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
反向代理单机
将测试文件放到默认发布目录里面(两台tomcat主机上)
bash
[root@localhost ~]# cp test.jsp /usr/local/tomcat/webapps/ROOT/
在nginx主机上:
bash
[root@localhost ~]# dnf install nginx -y
[root@localhost ~]# vi /etc/nginx/nginx.conf

bash
[root@localhost ~]# cd /etc/nginx/conf.d/
[root@localhost conf.d]# vim vhosts.conf
server{
listen 80;
server_name www.suyawen.org;
location ~ \.jsp$ {
proxy_pass http://172.25.254.101:8080;
}
}
[root@localhost conf.d]# systemctl start nginx
在C:\Windows\System32\drivers\etc\hosts文件中修改


单机情况下tomcat挂机,整体就用不了了;就用多机,既能负载均衡也能高可用
反向代理多机(两个tomcat负载均衡)
在vhosts.conf文件中

因为负载均衡所以在两个tomcat主机上来回轮询,导致填写信息不会永久保存(刚刚写入可能轮询下一个写入信息就没有了);因此要进行会话绑定。
会话绑定
不过这样的话同一个路由器过来的路由都会跑向一个路由器上了,就得用cookie哈希
cookie客户端生成的会话,session服务器生成的会话。会话:以用户的身份与服务器对话

在用户提交数据时,刚好所提交的tomcat挂机导致数据丢失如何解决呢?
**方法:**在tomcat后端挂着Memcached!
Memcached
简介
Memcached 只支持能序列化的数据类型,不支持持久化 ,基于Key-Value的内存缓存系统memcached 虽然没有像redis所具备的数据持久化功能,比如RDB和AOF都没有,但是可以通过做集群同步的方式,让各memcached服务器的数据进行同步,从而实现数据的一致性,即保证各memcached的数据是一样的,即使有任何一台 memcached 发生故障,只要集群中有一台 memcached 可用就不会出现数据丢失,当其他memcached 重新加入到集群的时候,可以自动从有数据的memcached 当中自动获取数据并提供服务。
Memcached 借助了操作系统的 libevent 工具做高效的读写。libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能封装成统一的接口。即使对服务器的连接数增加,也能发挥高性能。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能
Memcached 支持最大的内存存储对象为1M ,超过1M的数据可以使用客户端压缩或拆分报包放到多个key中,比较大的数据在进行读取的时候需要消耗的时间比较长,memcached 最适合保存用户的session实现session共享
Memcached存储数据时, Memcached会去申请1MB的内存, 把该块内存称为一个slab, 也称为一个page
Memcached 支持多种开发语言,包括:JAVA,C,Python,PHP,C#,Ruby,Perl等
memcached的安装与启用(两台tomcat下)
bash
[root@localhost ~]# dnf install memcached -y
#因为它是非关系型数据库,无客户端因此可下载telnet进行访问
[root@localhost ~]# dnf install telnet -y
[root@localhost ~]# systemctl start memcached
#查看默认端口
[root@localhost ~]# netstat -antlupe | grep memcached
tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN 983 98583 47560/memcached
tcp6 0 0 ::1:11211 :::* LISTEN 983 98584 47560/memcached
#改为监听支持ip的所有端口
[root@localhost ~]# vim /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 0.0.0.0,::1" #将原来的127.0.0.1改为0.0.0.0
[root@localhost ~]# systemctl restart memcached
[root@localhost ~]# telnet 172.25.254.101 11211
Trying 172.25.254.101...
Connected to 172.25.254.101.
Escape character is '^]'.
memcached 操作命令
五种基本 memcached 命令执行最简单的操作。这些命令和操作包括:
set
add
replace
get
delete
bash
#前三个命令是用于操作存储在 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
示例:
bash
[root@localhost ~]# telnet 172.25.254.101 11211
Trying 172.25.254.101...
Connected to 172.25.254.101.
Escape character is '^]'.
add les 0 60 2 #0 是否压缩 60 过期时间 4 字长
a1
STORED
add leekey1 0 60 3
les
STORED
#查看
get les
VALUE les 0 2
a1
END
#改
set les 0 60 5
hello
STORED
get les
VALUE leekey 0 5
hello
END
add leekey1 0 60 4
test
#删除
delete les
DELETED
get les
END
get leekey1
test
#清空
flush_all
OK
get leekey1
END
两个都搞好后,使用插件让tomcat在memcached里存东西(默认情况下tomcat不支持memcached)
session 共享服务器
msm 介绍

msm(memcached session manager)提供将Tomcat的session保持到memcached可以实现高可用。
项目早期托管在google code,目前在Github
github网站链接:https://github.com/magro/memcached-session-manager
支持Tomcat的 6.x、7.x、8.x、9.x
Tomcat的Session管理类,Tomcat版本不同
memcached-session-manager-2.3.2.jar
memcached-session-manager-tc9-2.3.2.jar
Session数据的序列化、反序列化类
官方推荐kyro
在webapp中WEB-INF/lib/下
驱动类
memcached(spymemcached.jar)
Redis(jedis.jar)
安装
查看本机memcached 版本,可在网站查询匹配插件版本
参考链接:https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration
bash
[root@localhost ~]# rpm -qa | grep memcached
memcached-selinux-1.6.9-7.el9.x86_64
memcached-1.6.9-7.el9.x86_64
将spymemcached.jar、memcached-session-manage、kyro相关的jar文件都放到Tomcat的lib目录
中,这个目录是 $CATALINA_HOME/lib/ ,对应本次安装就是**/usr/local/tomcat/lib**。
bash
[root@localhost lib]# ls
annotations-api.jar servlet-api.jar
asm-5.2.jar spymemcached-2.12.3.jar
catalina-ant.jar tomcat-api.jar
catalina-ha.jar tomcat-coyote-ffm.jar
catalina.jar tomcat-coyote.jar
catalina-ssi.jar tomcat-dbcp.jar
catalina-storeconfig.jar tomcat-i18n-cs.jar
catalina-tribes.jar tomcat-i18n-de.jar
ecj-4.20.jar tomcat-i18n-es.jar
el-api.jar tomcat-i18n-fr.jar
jasper-el.jar tomcat-i18n-ja.jar
jasper.jar tomcat-i18n-ko.jar
jaspic-api.jar tomcat-i18n-pt-BR.jar
jsp-api.jar tomcat-i18n-ru.jar
kryo-3.0.3.jar tomcat-i18n-zh-CN.jar
kryo-serializers-0.45.jar tomcat-jdbc.jar
memcached-session-manager-2.3.2.jar tomcat-jni.jar
memcached-session-manager-tc9-2.3.2.jar tomcat-util.jar
minlog-1.3.1.jar tomcat-util-scan.jar
msm-kryo-serializer-2.3.2.jar tomcat-websocket.jar
objenesis-2.6.jar websocket-api.jar
reflectasm-1.11.9.jar
[root@localhost ~]# systemctl restart tomcat.service
注:
t1和m1部署可以在一台主机上,t2和m2部署也可以在同一台。
当新用户发请求到Tomcat1时, Tomcat1生成session返回给用户的同时,也会同时发给memcached2备份。即Tomcat1 session为主session,memcached2 session为备用session,使用memcached相当于备份了一份Session
如果Tomcat1发现memcached2 失败,无法备份Session到memcached2,则将Sessoin备份存放在memcached1中
配置
修改tomcat配置
bash
[root@localhost ~]# vim /usr/local/tomcat/conf/context.xml

bash
[root@localhost ~]# systemctl restart tomcat.service

这下在挂机后数据也不会丢失