Nginx+Tomcat+Redis之Session 共享 - 容器单机版
一、docker构建redis集群
参考:豆包ai,使用docker搭建redis集群,示例容器归集 提取码:1234
1.1、准备阶段
-
下载基础镜像
bashdocker pull docker.gh-proxy.com/ubuntu:20.04 docker tag docker.gh-proxy.com/ubuntu:20.04 ubuntu:20.04 -
准备构建好的redis服务: 参考:redis安装
bash目录: /data/redis 目录结构: redis ├── bin │ ├── ... │ └── redis-server ├── conf │ └── redis.conf └── logs 包准备为: redis-7.2.12.tar.gz -
redis配置文件: /data/redis/bin/redis.conf
bash# 容器要运行在前台 daemonize no bind 0.0.0.0 # 其它的后续用的时候都会覆盖原始配置,它能起来一次测试就行 -
Dockerfile
bashfrom ubuntu:20.04 ADD redis-7.2.12.tar.gz /data ENV redis_home=/data/redis VERSION=7.2.12 EXPOSE 6379 CMD ["/data/redis/bin/redis-server","/data/redis/conf/redis.conf"] -
构建并检查服务是否正常
bash[root@localhost opt]# docker build -t redis:7.2.12 . [root@localhost opt]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE redis 7.2.12 1916e2f38ccd About a minute ago 149MB [root@localhost opt]# docker run -d -P --name t1 1916e2f38ccd [root@localhost opt]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 541721bbab2a 9bb "/data/redis/bin/red..." 2 seconds ago Up 1 second 0.0.0.0:32768->6379/tcp, :::32768->6379/tcp t2 # 本地redis不需要启动 [root@localhost opt]# /data/redis/bin/redis-cli -h 127.0.0.1 -p 32768 127.0.0.1:32768> auth xiong OK 127.0.0.1:32768> set 1 1 OK 127.0.0.1:32768> get 1 "1" -
做成集群其实也只是把它的原始配置文件覆盖
1.2、集群构建
-
准备配置文件 redis.conf
bash##################### 基础配置 port 6379 # 数据存储目录 dir /data/redis/conf # 前台运行 daemonize no # 日志文件 logfile /data/redis/conf/redis.log ##################### 集群核心配置 # 启用集群模式 cluster-enabled yes # 集群节点信息文件(自动生成/更新) cluster-config-file nodes.conf # 节点超时时间(毫秒,故障检测阈值) cluster-node-timeout 15000 # 从节点选举有效性因子(默认 10) cluster-replica-validity-factor 10 # 主节点最小从节点数(防止脑裂,默认 1) cluster-migration-barrier 1 ##################### 其他优化配置 bind 0.0.0.0 # 关闭保护模式(需配合密码或IP限制) protected-mode no # 节点密码(所有节点密码必须一致) requirepass xiong # 主从同步密码(与 requirepass 一致) masterauth xiong # 开启AOF持久化(保证数据不丢失) appendonly yes # AOF同步策略(每秒同步) appendfsync everysec -
自行定义网络段
bash# 自行定义名称吧 [root@localhost redisdata]# docker network create p1 --subnet 10.0.1.0/24 343183d2efbf260393cff935feead28c7b4730a76a74bc76e44a60dd7e14902f [root@localhost redisdata]# docker network ls 343183d2efbf p1 bridge local -
创建并复制配置文件
bash# 用上面准备好的redis配置文件 data]# for ((i=1;i<=6;i++));do mkdir /data/redisdata/redis$i -p;cp /data/redis.conf /data/redisdata/redis$i;done data]# tree redisdata/ redisdata/ ├── redis1 │ └── redis.conf ├── redis2 │ └── redis.conf ├── ..... -
运行六个容器
bashfor ((i=1;i<=6;i++));do docker run -d -p 637${i}:6379 --name redis-${i} -v /data/redisdata/redis$i:/data/redis/conf --net p1 --ip 10.0.1.10${i} redis:7.2.12 done # 详解一下 run -d # 后台运行容器 -p 637${i}:6379 # 端口映射 --name redis-${i} # 容器命名:redis-1-6 -v /data/redisdata/redis$i:/data/redis/conf # 数据卷挂载 --net p1 # 容器接入p1 网络 --ip 10.0.1.10${i} # 分配固定 IP:10.0.1.101-106 redis:7.2.12 # 使用Redis 7.2.12镜像 -
如果测试中失败
bash# 清掉无效的容器 docker rm $(docker stop $(docker ps -a -q)) -
构建集群
bashdocker exec -it redis-1 echo yes| /data/redis/bin/redis-cli -a xiong --cluster create 10.0.1.101:6379 10.0.1.102:6379 10.0.1.103:6379 10.0.1.104:6379 10.0.1.105:6379 10.0.1.106:6379 --cluster-replicas 1 # docker exec -it redis-1 指定redis-1 执行某个命令 # 免输yes, 详解看一下redis集群章节 echo yes| /data/redis/bin/redis-cli -a xiong --cluster create 10.0.1.101:6379 10.0.1.102:6379 10.0.1.103:6379 10.0.1.104:6379 10.0.1.105:6379 10.0.1.106:6379 --cluster-replicas 1 -
检查集群状态
bash# 查看集群16384糟点是否都正常分配 [root@localhost data]# docker exec -it redis-1 /data/redis/bin/redis-cli -a xiong cluster info Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_size:3 cluster_current_epoch:6 # 查看集群内节点分配的糟位,三主三从没问题 [root@localhost data]# docker exec -it redis-1 /data/redis/bin/redis-cli -a xiong cluster nodes Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. 9e3...c5a 10.0.1.102:6379@16379 master - 0 1763644282434 2 connected 5461-10922 066...120 10.0.1.104:6379@16379 slave 5ac...d21 0 1763644283478 3 connected 5ac...d21 10.0.1.103:6379@16379 master - 0 1763644281000 3 connected 10923-16383 801...8d8 10.0.1.106:6379@16379 slave 9e3...c5a 0 1763644281387 2 connected d5c...1c6 10.0.1.105:6379@16379 slave 3e5...540 0 1763644280000 1 connected 3e5...540 10.0.1.101:6379@16379 myself,master - 0 1763644280000 1 connected 0-5460 -
在检查挂载点
bashredisdata]# tree . ├── redis1 │ ├── appendonlydir │ │ ├── appendonly.aof.1.base.rdb │ │ ├── appendonly.aof.1.incr.aof │ │ └── appendonly.aof.manifest │ ├── dump.rdb │ ├── nodes.conf │ ├── redis.conf │ └── redis.log ├── redis2 ├── redis3 ....... -
此时都构建完毕
二、docker构建tomcat
2.1、准备阶段
-
基础镜像还是用:ubuntu:20.04
-
tomcat: 8.5.100 , jdk1.8.461
-
tomcat原理与安装,jar包看session章节,示例配置归集
bash# 准备集群版本的包 , 这五个jar包放到 tomcat/lib目录下面 commons-pool2-2.11.1.jar jedis-3.6.3.jar redis-session-cluster-plugin.jar slf4j-api-1.7.36.jar slf4j-simple-1.7.36.jar -
context.xml 用环境变量的方式试了好几种办法行不通,后续用
envsubst启动时动态生成context.xml成功-
压缩 tomcat.tar.gz前操作
-
删除
/data/tomcat/conf/context.xml(用模板文件替代)bashtomcat]# vi tomcat/conf/context.xml.template <?xml version="1.0" encoding="UTF-8"?> <Context> <WatchedResource>WEB-INF/web.xml</WatchedResource> <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource> <Resources cachingAllowed="true" cacheMaxSize="102400" /> <Valve className="com.naritech.nicole.gump.RedisSessionHandlerValve" /> <Manager className="com.naritech.nicole.gump.RedisSessionManager" nodes="$REDIS_CLUSTER_NODES" password="$REDIS_PASSWORD" database="0" maxInactiveInterval="1800" timeout="3000" maxRedirections="5" cluster="$REDIS_CUSTER_FLAG" /> </Context> -
将上面的
context.xml.template放到/data/tomcat/conf/目录下 -
此时目录结构
bash[root@localhost tomcat]# tree -L 3tomcat . ├── context.xml ├── Dockerfile ├── jdk1.8 ├── tomcat │ ├── bin │ │ ├── ... 默认tomcat脚本 │ │ ├── catalina.bat │ ├── conf │ │ ├── context.xml.template │ ├── lib │ │ ├── .... 其它默认jar │ │ ├── commons-pool2-2.11.1.jar │ │ ├── jedis-3.6.3.jar │ │ ├── redis-session-cluster-plugin.jar │ │ ├── slf4j-api-1.7.36.jar │ │ ├── slf4j-simple-1.7.36.jar │ ├── LICENSE │ ├── logs │ ├── NOTICE │ ├── README.md │ ├── RELEASE-NOTES │ ├── RUNNING.txt │ ├── temp │ ├── webapps │ └── work -
压缩:
tar zcf tomcat.tar.gz jdk1.8 tomcat
-
-
Dockerfile
bashfrom ubuntu:20.04 # 安装 gettext(包含 envsubst 工具,用于替换变量) RUN apt-get update && apt-get install -y gettext && rm -rf /var/lib/apt/lists/* ADD tomcat.tar.gz /data # 环境变量(默认值,运行时可覆盖) ENV JAVA_HOME=/data/jdk1.8 \ TOMCAT_HOME=/data/tomcat \ TOMCAT_VERSION=8.5.100 \ JAVA_VERSION=1.8.461 \ LC_ALL=en_US.UTF-8 \ REDIS_CLUSTER_NODES="1.1.1.1:6379" \ REDIS_PASSWORD="default" \ REDIS_CUSTER_FLAG="false" EXPOSE 8090 # 核心命令: # 1. 用 envsubst 替换模板中的变量,生成真正的 context.xml(纯硬编码) # 2. 启动 Tomcat CMD ["/bin/sh", "-c", "envsubst '$REDIS_CLUSTER_NODES $REDIS_PASSWORD $REDIS_CUSTER_FLAG' < $TOMCAT_HOME/conf/context.xml.template > $TOMCAT_HOME/conf/context.xml && $TOMCAT_HOME/bin/catalina.sh run"] ##### LC_ALL=en_US.UTF-8 <-- 解决容器内访问中文乱码 -
构建容器
bash[root@localhost opt]# docker build -t tomcatcluster:8.5.100 . [root@localhost opt]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tomcatcluster 8.5.100 ---------- 8 seconds ago 272MB
2.1、集群构建
-
准备jsp文件
bashmkdir /data/tomcatdata/webapps/ROOT -p mkdir /data/tomcatdata/logs -p vi /data/tomcatdata/webapps/ROOT/index.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.net.InetAddress" %> <%@ page import="java.net.NetworkInterface" %> <%@ page import="java.util.Enumeration" %> <%@ page import="java.io.File" %> <html> <head> <title>Tomcat 核心信息查询(含运行路径)</title> </head> <body> <h3>🎯 Tomcat 核心信息汇总</h3> <hr> <!-- 1. Session 会话信息 --> <p><strong>📌 Session 信息:</strong></p> <p>Session ID:<%= session.getId() %></p> <p>创建时间:<%= new java.util.Date(session.getCreationTime()) %></p> <p>最后活动时间:<%= new java.util.Date(session.getLastAccessedTime()) %></p> <p>会话超时时间:<%= session.getMaxInactiveInterval() / 60 %> 分钟</p> <hr> <!-- 2. 服务器(Tomcat 所在机)信息 --> <p><strong>🖥️ 服务器信息:</strong></p> <p>服务器主机名:<%= InetAddress.getLocalHost().getHostName() %></p> <p>服务器内网 IP 列表:</p> <ul> <% // 获取所有有效内网 IPv4(排除回环地址) Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces(); boolean hasIp = false; while (netInterfaces.hasMoreElements()) { NetworkInterface ni = netInterfaces.nextElement(); Enumeration<InetAddress> ips = ni.getInetAddresses(); while (ips.hasMoreElements()) { InetAddress ip = ips.nextElement(); if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && !ip.isLinkLocalAddress()) { out.println("<li>" + ip.getHostAddress() + "(网卡:" + ni.getDisplayName() + ")</li>"); hasIp = true; } } } if (!hasIp) out.println("<li>未获取到有效内网 IP</li>"); %> </ul> <hr> </body> </html> -
执行容器
bash# 启动新容器,传递环境变量(会被动态替换到 context.xml) docker run -d -P --net p1 --name tt1 \ -e REDIS_CLUSTER_NODES="10.0.1.101:6379,10.0.1.102:6379,10.0.1.103:6379,10.0.1.104:6379,10.0.1.105:6379,10.0.1.106:6379" \ -e REDIS_PASSWORD="xiong" \ -e REDIS_CUSTER_FLAG="true" \ -v /data/tomcatdata/webapps/:/data/tomcat/webapps/ \ -v /data/tomcatdata/logs/:/data/tomcat/logs/ \ tomcatcluster:8.5.100 -
检查是否生效
bash# 此时能看到文件都被替换了 [root@localhost tomcat]# docker exec -it tt1 cat /data/tomcat/conf/context.xml nodes="10.0.1.101:6379,10.0.1.102:6379,........9" password="xiong" cluster="true" -
也可以用 docker 容器name代替 <-- 我们用这个
bashdocker run -d -P --net p1 --name tt2 \ -e REDIS_CLUSTER_NODES="redis-1:6379,redis-2:6379,redis-3:6379,redis-4:6379,redis-5:6379,redis-6:6379" \ -e REDIS_PASSWORD="xiong" \ -e REDIS_CUSTER_FLAG="true" \ -v /data/tomcatdata/webapps/:/data/tomcat/webapps/ \ -v /data/tomcatdata/logs/:/data/tomcat/logs/ \ tomcat:8.5.100 [root@localhost tomcat]# docker exec -it tt2 cat /data/tomcat/conf/context.xml nodes="redis-1:6379,redis-2:6379,....6379"
三、docker构建nginx
3.1、准备阶段
-
基础镜像还是用:ubuntu:20.04
-
nginx原理与安装, 这里用nginx:1.29, 任意一个版本都行
-
目录及文件准备
bashnginx.conf <-- 如果是其它的 加上 include 也可以自行定 user root; include /data/nginx/conf/conf.d/*.conf; -
Dockerfile
bashfrom ubuntu:20.04 ADD nginx.tar.gz /data ENV nginx_home=/data/nginx VERSION=1.29.3 EXPOSE 8080 CMD ["/data/nginx/sbin/nginx", "-g", "daemon off;"] # 如果启动后报缺少nobody用户 需要加上 RUN useradd nobody -
构建
bashdocker build --no-cache -t nginx:1.29.3 -f Dockerfile . mkdir /data/nginxdata/conf/conf.d/cache -p -
tomcat.conf
bashvim /data/nginxdata/conf/conf.d/tomcat.conf # 我们直接指向它的 容器名称,由docker自行维护 upstream backend_servers { server tt2:8090 weight=1; # 服务器 1,权重 5(请求占比更高) server tt3:8090 weight=1; # 服务器 2,权重 3 } # 反向代理的 server 块 server { listen 8080; server_name 127.0.0.1; access_log /data/nginx/logs/access.log; # 所有请求转发到 backend_servers 集群 location / { proxy_pass http://backend_servers; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 30; proxy_read_timeout 60; } } -
运行容器
bashdocker run -d -P --name n2 --net p1 -v /data/nginxdata/conf/conf.d:/data/nginx/conf/conf.d nginx:1.29.3 -
查看并访问
bash[root@localhost nginx]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7ef5fc81d772 nginx:1.29.3 "/data/nginx/sbin/ng..." 5 minutes ago Up About a minute 0.0.0.0:32784->8080/tcp, :::32784->8080/tcp n2 # 浏览器访问 http://本机ip:32784 Session ID:3588FA1B135C8F53B54FC354A6A7DDE3 服务器主机名:bc0ab8300a65 服务器内网 IP 列表:10.0.1.4(网卡:eth0) # sessionID 会话保持成功 服务器主机名:9a0aaa78882b 服务器内网 IP 列表:10.0.1.3(网卡:eth0)
四、归集说明
-
测试中运行容器
bash[root@localhost nginx]# docker ps CONTAINER ID IMAGE PORTS NAMES 7ef5fc81d772 nginx:1.29.3 0.0.0.0:32784->8080/tcp n2 bc0ab8300a65 tomcat:8.5.100 0.0.0.0:32778->8090/tcp tt3 9a0aaa78882b tomcat:8.5.100 0.0.0.0:32777->8090/tcp tt2 715eb014f95d tomcatcluster:8.5.100 0.0.0.0:32776->8090/tcp tt1 93dcac7c3ae0 redis:7.2.12 0.0.0.0:6376->6379/tcp redis-6 ec5d3b969e7c redis:7.2.12 0.0.0.0:6375->6379/tcp redis-5 2c7ddfa15364 redis:7.2.12 0.0.0.0:6374->6379/tcp redis-4 a1a0b0ac4d57 redis:7.2.12 0.0.0.0:6373->6379/tcp redis-3 e581687184ff redis:7.2.12 0.0.0.0:6372->6379/tcp redis-2 64a59bd26870 redis:7.2.12 0.0.0.0:6371->6379/tcp redis-1 -
容器名称
bash[root@localhost nginx]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx 1.29.3 318b6eff3815 12 minutes ago 82.5MB tomcatcluster 8.5.100 b25b27e2e6d7 2 hours ago 339MB redis 7.2.12 5994741e64ea 5 hours ago 149MB ubuntu 20.04 b7bab04fd9aa 7 months ago 72.8MB [root@localhost nginx]# docker save -o nginx-1.29.3.tar.gz 318b6eff3815 [root@localhost nginx]# docker save -o tomcatcluster-8.5.100.tar.gz b25b27e2e6d7 [root@localhost nginx]# docker save -o redis.7.2.12.tar.gz 5994741e64ea [root@localhost nginx]# docker save -o ubuntu.20.04.tar.gz b7bab04fd9aa