同一台服务器,多个Tomcat,部署同一个项目session覆盖的问题
最近一段时间,在开发环境部署多套项目,其中一套用于对外调试,一套内部开发测试,限于资源有限,也使为了方便管理,就在同一台机器上创建了两个Tomcat。所以就有了如题目所描述的场景,一台服务器中多个Tomcat,而且Tomcat里部署的项目都是一样的。
遇到的问题
简单描述一下,那台机器中服务器和项目的配置,TomcatA和TomcatB,里面同事部署了projectTest项目。配置好了后,开始用得好好的,偶然发现打开一个浏览器,先访问一下TomcatA的projectTest,登录进去了,然后开启一个新的标签页,访问TomcatB的projectTest,然后再访问TomcatA的projectTest,会发现需要重新登录了。这个过程可以如下步骤表述:
-
1.访问TomcatA的projectTest项目,登录进去。
-
2.同一个浏览器,新开一个标签页,访问TomcatB的projectTest项目。
-
3.回到TomcatA的projectTest项目刷新一下,会发现需要重新登录。
其实在在第2步操作时,session就已经发生了覆盖了。
发生session覆盖的原因
因为是同一台机器,所以IP是一样的,项目也是一样,只有端口是不同的;在步骤1,访问TomcatA的项目时,会返回一个JSESSIONID
给客户端,客户端会根据IP+项目名
作为一个站点的标识,与cookies中的JSESSIONID
关联起来。当你向TomcatB的项目发起访问时,浏览器根据你访问的URL,解析得到你的IP+项目名,找到TomcatA关联的cookies,也发给了TomcatB,而TomcatB根本没有这个JSESSIONID
,所以会重新生成一个返回给浏览器,那么新的JSSESSIONID
的cookies又会跟IP+项目名
关联;同理,此时的JSESSIONID
已经不是TomcatA最初的JSESSIONID
了,所以第3步访问TomcatA的项目,会导致发现session丢失或者说被覆盖了的现象。
解决方案
直接改下conf文件下的context.xml
的context标签, 修改Tomcat返回的JSESSIONID的名字,如:SessionCookieName=”JSESSIONID_1”
,设置一个名字(默认是JSESSIONID) ;那么上面例子中,我们将TomcatA改为SessionCookieName=”JSESSIONID_A”
,TomcatB改为SessionCookieName=”JSESSIONID_B”
;,这个的原理就是通过让每个Tomcat的为项目返回的SessionID的名字不重复,所以即使TomcatA的JSESSIONID_A
发往TomcatB,TomcatB没有这个JSESSIONID_A
,它会产生一个JSESSIONID_B
,此时返回给浏览器的JSESSIONID_B
因为与JSESSIONID_A
不同而不会发生覆盖,因此可以解决该问题。