跨应用Session共享
跨应用Session共享
Why Session Share?
在日常的开发过程中,我们经常会遇到这样的一个开发场景:一个项目比较大,开发的周期比较长,需要按照产品线或者是功能把它切分成若干个子项目,然后分配给不同的团队同时进行开发,这样做既有利于缩短开发周期,同时也给我们在项目维护上带来便利。举个例子,拿网上银行系统开发来说,整一个项目可能会切割成Login / Account / Banking / Cards / Insurance / Investments等子项目。
拿到项目需求之后我们就各自开展自己的工作,在项目开发中,我们使用Session来记录用户的状态以及保存客户端与服务器之间的交互信息。但是随着项目的深入,我们发现,在不同的项目之中,我们除了需要维护自己项目的Session信息之外,还需要在项目之间共享Session信息。比如说Insurance项目,需要Login项目提供Customer的Customer Segment,需要Account项目提供Customer的Account Information等等。
这就引出了我们今天的话题,部署在同一台服务器上的不同应用之间,如何实现Session共享的问题。
项目Demo:
为了更好的理解Session跨应用共享的问题,让我们在Eclipse上面创建以下3个项目,并分别创建各自的Servlet Class跟Configure,如下所示:
如上所示,我们分别在Login跟Account项目的Session对象中Put进去了Customer Segment跟Customer Account,并试图在Insurance当中把它们获取出来。我们把这三个项目同时部署到Tomcat服务器,并分别依次运行LoginServlet/AccountServlet/InsuranceServlet,我们期望可以在Insurance当中获取之前Session当中设置的值,可是非常遗憾,控制台输出了null / null。
为了更好的追踪问题,在各自项目的Servlet Class当中,我们把当前的Session ID打印出来,看看它们是不是相同的。编译完之后重新部署我们的项目,运行Tomcat,我们可以在控制台看到如下的输出:
从上面控制台的输出我们可以看到,Tomat服务器默认为每个项目分配各自的Session,因此在Insurance项目中当然获取不到其他子项目的Session内容。如下图所示:
按照Servlet规范,Session的作用范围应该仅仅限于当前的应用程序,不同的应用程序之间是不能够互相访问对方Session。各个应用服务器都遵守了这一规范,但实现的细节却可能各有不同 。
从上面的例子看,Tomcat服务器默认为每一个Application分配一个Session ID唯一的Session对象。但并不是所有的服务器都是遵循这样的实现,笔者从事的公司使用的是IBM的WebSphere Application Server,它为所有部署在同一服务器上的Application分配的Session对象都使用相同的Session ID,但当你试图跨应用获取Session信息的时候,你会发现依然失败。此类服务器虽然为所有的Seesion对象分配了相同的Session ID,但是所生成的Session对象却是跟当前的Application紧密相关的,从而确保了当前的应用只能够使用自己的Session对象。因此,我们不能够仅仅从Session ID入手实现Session的跨应用共享。
如何跨应用共享Session:
归根结底,跨应用Session共享的最终目的就是把Session的信息存放都一个大家都可以访问到的地方,最后各个应用都去那里获取都共享的Session信息,我们可以通过以下的方法来实现这个效果:
- 把Session信息作为URL参数或者是隐藏表单字段传递,在各个应用之间实现Session共享(从安全性,便捷性不推荐此做法);
- 把Session信息写入Cookie,各个应用从Cookie中获取共享的信息。但由于Cookie自身的安全性跟文件大小的限制,使用这种方法的时候要谨慎权衡利弊;
- 把Session信息写入到服务器的某一个路径下的指定的文件当中,各个应用需要的时候在从这个文件当中读取Session的信息。但是这种方法涉及到IO操作,对读写速度,服务器开销存在一定的影响,而且在高并发访问的背景下,我们还需要考虑到数据脏读的问题;如果文件丢失,那么所有的应用都无法正常工作。
- 把Session信息写入到数据库中,各个应用需要的时候再从数据库中读取相对应的Session信息。这种方法可行,但是需要引入数据库的支持,而且在高并发访问下存在着频繁读写数据库的问题,对性能依旧是一个考验;
- 把Session信息写入到服务器JNDI中,实现各个应用的Session共享;
- 把一个应用的Session放入ServletContext对象中,在另一个应用中从ServletContext获取出前一个应用的Session对象,实现Session共享;使用这种方法的前提是跨ServetContext没有被服务器禁用。
上面罗列了一些我们在同一个服务器单一实例中,如何实现跨应用共享Session的一些常用的方法,总而言之,跨应用共享Session的目的就是把Session信息存放到一个大家都可以读写的地方。具体使用哪种方法,需要综合安全性,操作便捷性,使用成本和性能来综合考虑。
我要小额赞助,鼓励作者写出更好的文章:
posted on 2018-03-04 11:13 WebOpenShare 阅读(715) 评论(2) 编辑 收藏 举报