Nginx+tomcat集群中,session的共享

时间:2022-05-25 07:17:52

nginx,tomcat集群后多个session分配到同一个应用

单节点低负荷的情况下,我们通常把一个WEB应用打成WAR包放WEB应用服务器,如TOMCAT下运行就行了(如图1)。但随着用户量的增加,系统负载日益增长,这时我们通常就会采用多台WEB应用服务器组成集群来分担负荷(tomcat1, tomcat2上同时部署了应用application1; tomcat3上单独部署了应用application3),这时某一用户对同一应用的访问就有可能分配到从不同的TOMCAT访问这个应用(如图2, session1和session2同时访问application1)。假设我们的WEB访问请求都是无状态的,多个后台应用和一个后台应用的处理就没什么区别了,根据每次请求的参数进行相关逻辑处理就行。但通常我们会将用户信息,鉴权的数据等放入session中做用户鉴权, 用户状态数据等基础框架的处理,这时我们每次分配到WEB服务器后台的访问请求就需要记录session状态及数据了,确保每次用户访问,后台从session取出的数据是一致的。

Nginx+tomcat集群中,session的共享

Nginx+tomcat集群中,session的共享

到这里,我们已经可以清楚的看到,集群环境下,某一用户请求访问APPLICATION1,第一次请求被NGINX转发到TOMCAT1,产生了SESSION1,这时,APPLICATION1存了某一数据进SESSION1。随后,该用户进行第二次请求,这时,NGINX将该请求转发到TOMCAT2,这时TOMCAT2产生了一个新的SESSION2来访问APPLICTION1,如果这时APPLICTION1从SESSION中取刚存入的数据,因为SESSION2是TOMCAT2新产生的,并不是刚才存入数据的SESSION1,就会取不到我们想要的数据.

所以,很自然的,我们就想到需要保持session1和session2的一致性。

而保持session1和session2的一致性有两种很明显的方法,一种是保持session1和session2中的数据一致,二是让session1和session2成为一个session,即如果同一用户访问applcation1, tomcat1和tomcat2产生的是一个共享的session。下面就介绍下这三种处理方式.

1. TOMCAT间的 session复制。

顾名思义,就是把一台TOMCAT上session发生变更的时候, 将变更的数据分发给其他TOMCAT。如图3

Nginx+tomcat集群中,session的共享

tomcat间是以IP组播发送变更的数据,将数据发送到集群组的其他成员。这里,同一用户访问APPLICATION1的session数据互相有了同步,他们的数据是相同的,就用app1sesson表示。

配置方法是配置 conf/server.xml 文件中的 Manager ,Channel,以及WEB.XML的distributable 属性。

修改 tomcat 的 conf 目录下的 context.xml 文件: 
  <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"    
  memcachedNodes="n1:localhost:11211 n2:localhost:11212"    
  failoverNodes="n2"    
  requestUriIgnorePattern=".*\.(png|gif|jpg|css|js)$"    
  sessionBackupAsync="false"    
  sessionBackupTimeout="100"    
  transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"    
  copyCollectionsForSerialization="false"    />

以上是以 1.3 版为例子,需要用的 jar 包: 
memcached-session-manager-1.3.0.jar 
msm-javolution-serializer-1.3.0.jar 
javolution-5.4.3.1.jar 
memcached-2.4.2.jar

2. 采用 memcached session manager 共享session。

Nginx+tomcat集群中,session的共享

这里, tomcat1和tomcat2产生的session1和session2 在 session mananger 的管理下,都使用的是缓存中的共享session,访问应用时这样传到application1应用的session就是图中的共享session.

3.nginx+redis+tomcat集群部署实现session共享

redis 实现: 
网址:https://github.com/jcoleman/tomcat-redis-session-manager 
同样修改 tomcat 的 conf 目录下的 context.xml 文件: 
以上是以 1.2 版为例子,需要用的 jar 包: 
tomcat-redis-session-manager-1.2-tomcat-6.jar 
jedis-2.1.0.jar 
commons-pool-1.6.jar

Tomcat配置(tomcat7)

1.将tomcat-redis-session.jar, jedis-2.7.2.jar  ,commons-pool2-2.4.1.jar放入所有tomcat的lib中

2.配置所有tomcat/conf/context.xml文件添加如下内容,配置

session共享

<?xml version='1.0' encoding='utf-8'?>

<Context>

<WatchedResource>WEB-INF/web.xml</WatchedResource>

<!-- tomcat-redis-session

共享配置 -->

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />

<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"

host="localhost"

port="6379"

database="0"

maxInactiveInterval="60" />

</Context>

换种写法:

首先,是配置tomcat,使其将session保存到redis上。有两种方法,也是在server.xml或context.xml中配置,不同的是memcached只需要添加一个manager标签,而redis需要增加的内容如下:(注意:valve标签一定要在manager前面。)

<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />
<Manager className="com.radiadesign.catalina.session.RedisSessionManager"
host="192.168.159.131"
port="16300"
database="0"
maxInactiveInterval="60"/>

其次,配置nginx,用于测试session保持共享。

upstream  redis.xxy.com  {
server 192.168.159.130:8081;
server 192.168.159.130:8082;
} log_format www_xy_com '$remote_addr - $remote_user [$time_local] $request '
'"$status" $body_bytes_sent "$http_referer"'
'"$http_user_agent" "$http_x_forwarded_for"'; server
{
listen 80;
server_name redis.xxy.com; location / {
proxy_pass http://redis.xxy.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
} access_log /data/base_files/logs/redis.xxy.log www_xy_com;
}

最后,将你的应用放到两个tomcat中,并依次启动redis、tomcat、nginx。访问你的nginx,可以发现两个tomcat中的session可以保持共享了。

4.测试

session共享(需要在tomcat中放置一个简单web项目)

启动redis

启动nginx

启动所有tomcat 访问:http://localhost/9999

不停的刷新页面,发现页面的sessionID不变;关闭某个tomcat继续刷新页面,发现sessionID

也不变。说明环境配置成功

所有需要的资源会打包一起