您的位置:首页 > 运维架构 > Tomcat

session共享问题(一)----同一tomcat多个应用session问题

2016-09-13 11:31 363 查看
问题描述:

最近一直在研究session共享的问题,现在分享一下我最近对这个问题的理解。这需要分不同情况下,不同的项目部署情况对应的解决方式也不一样。今天我讲的是一个简单的情况(一般也只有小型的项目才会有这种情况,现在大项目都用到集群,分布式)------------同一个tomcat下多个应用之间的session共享情况

应用场景:

现在项目都模块化,一个大项目分成多个小项目,而且用户登录注册独立成一个小项目,这时候如果其它小项目要从用户项目中拿用户项目中拿session数据,这时候就要面临同一个tomcat多个应用之间的session共享问题了

解决思路:

1、直接将session数据放到公共地方,redis或数据库或 cookies(小项目可以这样做)

2、直接session共享,从用户中心拿(只使用同一个tomcat)

解决问题前你要了解一下情况:

同一台服务器, 安装两个tomcat ,端口不一样, 姑且分别称为tomcat1 和 tomcat2, 在两个tomcat下分别都部署了A和B两个项目

同一个浏览器访问同一个tomcat的不同项目: 访问tomcat1(tomcat2)的A并登陆, 再访问tomcat1(tomcat2)的B , 测试结果两个项目的访问互不干扰;

同一个浏览器访问不同tomcat的不同项目: 访问tomcat1的A并登陆, 再访问tomcat2的B, 测试结果两个项目的访问互不干扰;

同一个浏览器访问不同tomcat的相同项目: 访问tomcat1的A(B)项目并登陆, 再访问tomcat2的A(B), 测试结果访问tomcat2的A(B)项目之后, 造成了sessionID的覆盖,使之前登录过的tomcat1的A(B)项目的session失效;

解决方案(主要讲第二种):
1、修改tomcat的server.xml文件

每一个web应用程序都有唯一一个ServletContext实例对象,被该web应用下面的每一个servlet共享。通过修改tomcat的server.xml,使不同web应用的ServletContext可以互相访问。然后,用ServletContext的setAttribute()方法把session存入ServletContext中,在另一个web程序就可以用getAttribute()方法取得传递过来的session。

server.xml文件修改如下:

<Host name="localhost"  appBase="webapps"unpackWARs="true" autoDeploy="true">
<Context path="/WebappA"  debug="9" reloadable="true" crossContext="true"/> //WebappA为项目名,crossContext="true"  //是关键
<Context path="/WebappB"  debug="9" reloadable="true" crossContext="true"/>
</Host>


crossContext属性的意思是:如果设置为true,你可以通过ServletContext.getContext() 调用另外一个WEB应用程序,获得ServletContext 然后再调用其getAttribute() 得到你要的对象。

Java代码如下:

WebappA:

HttpSession session = request.getSession();
session.setAttribute("userId", "test");
ServletContext ContextA =session .getServletContext();
ContextA.setAttribute("session", session );


WebappB:

HttpSession sessionB = request.getSession();
ServletContext ContextB = sessionB.getServletContext();
ServletContext ContextA= ContextB.getContext("/WebappA");// 这里面传递的是 WebappA的虚拟路径
HttpSession sessionA =(HttpSession)ContextA.getAttribute("session");
System.out.println("userId: "+sessionA.getAttribute("userId"));


总结:

其实这种项目部署的情况一般不太会有,一般大公司都是集群部署的。小公司的项目还是有可能用到这种情况。

如有不错的地方尽情的提,哈哈
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: