Nginx+Tomcat集群Redis共享session方案

张开发
2026/5/30 22:00:34 15 分钟阅读
Nginx+Tomcat集群Redis共享session方案
一、分布式Session共享方案的由来客户端浏览器访问服务器的时候服务器把客户端信息以某种形式记录在服务器上这就是 Session。客户端浏览器再次访问时只需要从该 Session 中查找该客户的状态就可以了。在实际工作中我们建议使用外部的缓存设备来共享 Session避免单个服务器节点挂掉而影响服务共享数据都会放到外部缓存容器中。使用Redis实现共享session所有服务器的session信息都存储到了同一个Redis集群中即所有的服务都将 Session 的信息存储到 Redis 集群中无论是对 Session 的注销、更新都会同步到集群中达到了 Session 共享的目的。Cookie是服务器写给客户端的文件也可以称为浏览器缓存。保存在客户端浏览器中而 Session 保存在服务器上。二、常见的session集群方案传统的session由服务器端生成并存储当应用进行分布式集群部署的时候如何保证不同服务器上session信息能够共享呢两种实现方式1.不同服务器上session数据进行复制2.session集中存储(session共享)redismemcachedhbase等两种方式的优缺点一目了然.Session复制是指session信息会在集群节点之间复制每个节点服务器上都会有相同的session信息。优点: 是即使一个节点服务器宕机了只要还有服务器存活就不影响用户使用。缺点: 缺点是node之间通信频繁响应速度有影响多并发、高频操作的情况下性能下降比较厉害。Session共享基于Memcache/Redis等数据库的session共享。tomcat自带集群中提供了session复制session信息会在各个tomcat中同步对网络要求较高session内存消耗影响会很大,对于小集群够用了大集群还是建议使用redis或者memcache进行session共享。因此构建tomcat集群时可以使用tomcat基于redis的session共享机制。而在通过nginx构建集群时也涉及session的问题.如下图所示架构:在nginx的集群架构下,可根据设置的nginx负载均衡算法的不同session的实现机制也不相同例如轮询默认指定权重fair第三方url_hash第三方负载算法时集群各个节点之间必须通过session共享来实现。要避开session问题,可以使用nginx的ip_hash算法此算法将用户的请求统一发送到同一个节点服务器上如不考虑节点服务器宕机的情况可不考虑session问题。但是节点服务器宕机后用户需要关掉浏览器从新打开登录才能恢复正常这样体验会变得很差。因此session共享在集群架构中有很大的用途。三、应用环境介绍1、session应用工具由于客户要使用Tomcat集群因此需要解决session共享的问题。在网上有很多解决方案比如通过Memcached来实现通过Redis来实现的相信很多同学都是通过jcolemanhttps://github.com/jcoleman/tomcat-redis-session-manager 的redis解决方案但是此方案仅支持tomcat6和7要支持tomcat8或9需要修改代码然后打包部署非常麻烦。因此强烈不推荐此种方案。这里主要介绍另一个更为简单的方案redisson支持最新的JDK和各个版本的tomcat6/7/8/9/10官网https://redisson.org/ 。redisson是redis官网推荐的java语言实现分布式锁的项目。当然redisson远不止分布式锁还包括其他一些分布式结构。例如分布式应用分布式缓存分布式回话管理分布式服务任务延迟任务执行器分布式redis客户端等。而我们这里要使用的是redisson提供的Tomcat Session Manager功能。Tomcat session共享的github地址为https://github.com/redisson/redisson/tree/master/redisson-tomcat2、环境准备首先说明下此案例的应用环境1三台物理机或虚拟机使用RHEL9/Almalinux9.1系统172.16.213.28、172.16.213.29、172.16.213.302redis7.x版本3JDK1.8版本4tomcat9.x版本5nginx1.23版本其中172.16.213.28服务器安装redis和tomcat1172.16.213.29安装tomcat2.172.16.213.30安装nginx通过nginx的负载均衡功能实现tomcat1和tomcat2的负载均衡进而判断两个tomcat实例是否实现了session共享。四、nginxtomcatredis部署过程整个部署过程很简单分别三个步骤分别介绍如下1、redis安装部署redis安装部署比较简单首先从https://redis.io 下载最新版本的redis这里下载的是redis7.x版本然后编译即可过程如下[rootlocalhost ~]# tar zxvf redis-7.0.9.tar.gz [rootlocalhost ~]# cd redis-7.0.9 [rootlocalhost redis-7.0.9]# make [rootlocalhost redis-7.0.9]# make install [rootlocalhost redis-7.0.9]# cp redis.conf /etc #拷贝配置文件到/etc目录下2、配置redis并启动打开redis配置文件/etc/redis.conf,修改两个配置项的值为如下内容bind 0.0.0.0 daemonize yes protected-mode no最后启动redis服务即可[rootlocalhost ~]# /usr/local/bin/redis-server /etc/redis.conf3、tomcat安装部署部署tomcat之前需要先安装JDK这里选择JDK1.8版本从oracle官网下载linux-64版本的JDK下载时选择适合自己机器运行环境的版本oracle官网提供的JDK都是二进制版本的因此JDK的安装非常简单只需将下载下来的程序包解压到相应的目录即可。安装过程如下[rootlocalhost ~]# mkdir /usr/java [rootlocalhost ~]# tar -zxvf jdk-8u201-linux-x64.tar.gz -C /usr/java/这里我们将JDK安装到了/usr/java/目录下。接着要让程序能够识别JDK路径还需要设置JDK的环境变量这里我们将JDK环境变量设置到/etc/profile文件中。添加如下内容到/etc/profile文件最后export JAVA_HOME/usr/java/jdk1.8.0_201 export PATH$PATH:$JAVA_HOME/bin exportCLASSPATH.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH然后执行如下命令让设置生效[rootlocalhost ~]# source /etc/profile最后在Shell提示符中执行“java -version”命令如果显示如下结果说明安装成功[rootlocalhost ~]# java -version java version 1.8.0_201 Java(TM) SE Runtime Environment (build 1.8.0_201-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)JDK部署成功后就可以部署tomcat了tomcat的安装很简单从http://tomcat.apache.org/ 下载最新的tomcat然后解压即可这里下载tomcat9版本安装到/usr/loca/目录下执行如下操作[rootlocalhost ~]# tar zxvf apache-tomcat-9.0.72.tar.gz -C /usr/local [rootlocalhost ~]# mv /usr/local/apache-tomcat-9.0.72 /usr/local/tomcat9这样tomcat也安装完成了。4、tomcat与redis整合实现session共享接下来就是配置tomcat了要配置tomcat和redis整合实现session管理需要几个步骤。1、部署jar包根据github上的说明 需要下载两个jar包根据我们的环境分别是redisson-all-3.20.0.jar和redisson-tomcat-9-3.20.0.jar这两个jar包都可以从https://github.com/redisson/redisson/tree/master/redisson-tomcat 下载。在最新的redisson版本中,还需要另一个依赖jar包fst,我这里下载的是fst-2.57.jar,如果没有此jar包,tomcat启动会出错,将下载下来的jar包放到$TOMCAT_BASE/lib目录下即可我们这里的路径是/usr/local/tomcat9/lib。2、增加RedissonSessionManager配置这个步骤是在tomcat的配置文件$TOMCAT_BASE/conf/context.xml中添加如下配置Manager classNameorg.redisson.tomcat.RedissonSessionManager configPath${catalina.base}/conf/redisson.json readModeREDIS updateModeDEFAULT/其中{catalina.base}/conf/redisson.json文件内容如下{ singleServerConfig:{ idleConnectionTimeout:10000, connectTimeout:10000, timeout:3000, retryAttempts:3, retryInterval:1500, password:null, subscriptionsPerConnection:5, clientName:null, address: redis://172.16.213.28:6379, subscriptionConnectionMinimumIdleSize:1, subscriptionConnectionPoolSize:50, connectionMinimumIdleSize:32, connectionPoolSize:64, database:0, dnsMonitoringInterval:5000 }, ​ threads:0, nettyThreads:0, codec:{ class:org.redisson.codec.FstCodec }, transportMode:NIO }需要注意这里面的address一项的值如果tomcat和redis安装在一起可以写成127.0.0.1:6379如果redis在独立的一台机器上就写redis所在机器的IP地址。这里redis所在的IP为172.16.213.28所以上面就写这个地址即可。到此为止tomcat与redis的互联配置完成。5、测试获取session在tomcat的$TOMCAT_BASE/webapps/ROOT目录下创建一个testsession.jsp文件内容如下% page languagejava importjava.util.* pageEncodingutf-8% % String path request.getContextPath(); String basePath request.getScheme() :// request.getServerName() : request.getServerPort() path /; % !DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN html head meta http-equivContent-Type contenttext/html; charsetutf-8 / titletomcat1/title /head ​ body centerh1tomcat1/h1/center center h3sessionId:/h3%session.getId()% h3session创建时间/h3%session.getCreationTime()% center /body /html接着启动tomcat服务执行如下命令[rootlocalhost ~]#/usr/local/tomcat9/bin/startup.sh启动tomcat后在浏览器访问http://172.16.213.28:8080/testsession.jsp, 如下图所示然后登录redis客户端查看key信息如下图所示[rootlocalhost ~]#redis-cli 127.0.0.1:6379 keys * 1) redisson:tomcat_session:3C9CCFDD65022303DDCEDB1180A1703A 127.0.0.1:6379可以看到redis里面已经生成了session信息。6、部署第二个tomcat实例上面已经部署好了第一台tomcat实例tomcat1接着在172.16.213.29上部署另一个tomcat实例tomcat2最简单的部署方法是直接拷贝第一个tomcat1实例到172.16.213.29上对应的位置即可。为了两个tomcat实例进行区分这里需要修改testsession.jsp文件中的一些标识信息修改后的内容如下% page languagejava importjava.util.* pageEncodingutf-8% % String path request.getContextPath(); String basePath request.getScheme() :// request.getServerName() : request.getServerPort() path /; % ​ !DOCTYPE HTML PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN html head meta http-equivContent-Type contenttext/html; charsetutf-8 / titletomcat2/title /head ​ ​ body centerh1tomcat2/h1/center center h3sessionId:/h3%session.getId()% h3session创建时间/h3%session.getCreationTime()% center /body ​ /html这里主要是将文件中的tomcat1修改为了tomcat2最后还需要在172.16.213.29上安装和配置JDK这个上面已经做了介绍这里不再说明。所有修改完成后启动tomcat服务然后访问http://172.16.213.29:8080/testsession.jsp, 如下图所示可以看到通过172.16.213.28和172.16.213.29访问testsession.jsp页面得到的session信息是不一样的。这是正常的。7、部署nginx负载均衡根据上面的定义nginx是安装在172.16.213.30服务器上从nginx官网http://nginx.org/ 下载最新的nginx版本这里是nginx-1.23版本然后进行编译安装过程如下[rootcentos ~]# yum -y install zlib pcre pcre-devel openssl openssl-devel [rootcentos ~]# useradd -s /sbin/nologin www [rootcentos ~]#tar zxvf nginx-1.23.3.tar.gz [rootcentos ~]#cd nginx-1.23.3 [rootcentos nginx-1.23.3]# ./configure \ --userwww \ --groupwww \ --prefix/usr/local/nginx \ --sbin-path/usr/local/nginx/sbin/nginx \ --conf-path/usr/local/nginx/conf/nginx.conf \ --error-log-path/usr/local/nginx/logs/error.log \ --http-log-path/usr/local/nginx/logs/access.log \ --pid-path/var/run/nginx.pid \ --lock-path/var/lock/subsys/nginx \ --with-http_stub_status_module \ --with-http_ssl_module \ --with-http_gzip_static_module \ --with-pcre [rootcentos nginx-1.23.3]# make [rootcentos nginx-1.23.3]# make install这样nginx就安装完成了。接下来就是配置nginx了打开nginx配置文件nginx.conf重点修改如下部分内容user www; worker_processes 8; events { worker_connections 65536; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; upstream tomcat { server 172.16.213.28:8080 weight1; server 172.16.213.29:8080 weight1; } ​ server { listen 80; server_name localhost; ​ location / { proxy_pass http://tomcat; } ​ error_page 500 502 503 504 /50x.html; location /50x.html { root html; } ​ } }最后启动nginx即可[rootcentos nginx-1.23.3]# /usr/local/nginx/sbin/nginx五、测试nginxtomcatredis的session共享功能nginx配置完成后就可以通过http://172.16.213.30/testsession.jsp 访问两个tomcat实例了如下图所示可以看到如果不停刷新这个页面的话会在两个tomcat实例之间来回轮询切换但session值并不发生变化这说明两个tomcat实例都共享了redis里面存储的session信息也就是实现了nginxtomcatredis的session共享功能。

更多文章