技术开发 频道

为什么要关注session的创建

  【IT168 技术文档】看到有留言,对我如此“执着”的关注session创建很好奇,解释一下吧。

  首先是关注性能,前面提到过session的使用是有代价的,需要在保存在服务器端内容中,每次request.getSeesion()方法获取session时,实际是在服务器段的一个大的hasp结构中以当前的jsessionid为key,获取对应的value HttpSession对象,这个过程是需要消耗cpu的,当然目前hash算法比较好,这里消耗不那么明显。而一般的应用,消耗的cpu远比这个小开销大出2-3个数量级,因此通常情况不敏感。如果这个session是我们需要使用的,那么付出这些内存和cpu的代码是完全值得的。但是,如果产生大量的没有任何用处的"垃圾session",对大容量,大并发,需要长期稳定运行的系统会带来很无谓的负载。

  注意,我们要讨论是"垃圾session",即是在我们计划外因为某个原因创建,从不使用,完全浪费的session。正常使用的session不在讨论范围内,虽然也有些比较极端的系统号称不使用session来提高服务器性能,有些对性能比较关注的系统/框架则采用其他的方式来避免使用session,有兴趣的可以google找资料看。

  下面我们来进行一个简单的性能测试,模拟一下比较极端的情况,我在linux下启动resin,只跑两个最简单的jsp文件:

  a.jsp不会自动生成session: 

<%@ page contentType="text/html; charset=UTF-8" %> <%@ page session="false" %> <!DOCTYPE html PUBLIC "-//W3C/m/DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> </head> <body> <%=1%> </body> </html>

  b.jsp基本相同,但是设置为,这个将自动增加

  HttpSession session = request.getSesson(true)

  语句,我们进行最恶劣的假设,每次请求都生成新的session,看看会是什么情况:

  测试工具采用loadrunner,部署在我的笔记本上(dell d620机器,intel 双核 2g内存)。测试比较简单,测试方法和过程忽略(loadrunner的使用也不复杂),只给出结果:

  测试中两个场景的运行情况相同:100个线程并发,每次只访问一下a.jsp/b.jsp,运行时间2分钟。使用top命令在服务器段看resin的内存消耗和cpu使用情况,这个只能大概估计,不好准确衡量。

  测试1:

  a.jsp 不生成session

  resin内存消耗始终是在175-177之间,基本没有变化。cpu基本稳定在19%-22%。

  测试2:

  b.jsp 每次生成session

  resin内存消耗从175逐步增加,到2分钟测试结束时达到204,大概增加了30M。cpu大体在25%-30%间。

  两次测试的页面请求数基本相当,182000和181000,忽略微小差异取180000来计算,30M内存/180000次请求=174字节。(这里可能有个小问题,目前还不确认是否是真的生成了180000个session,下次有时间写个SesionLinstener来计算看看)。

  下面可以总结了:

  1. 垃圾session会占用内存

  上面只测试了2分钟,考虑通常session的超时时间会是30分钟,这意味着这些占据的内存至少要到30分钟之后resin才能判定超时从resin的session hash结构出移

  除,之后再被jvm回收。

  2. 垃圾session的调用消耗了cpu资源

  HttpSession session = request.getSesson(true),每次都要new出新的HttpSession对象,然后resin还要给这个HttpSession算出一个jsessionid,再将

  jsessionid/session以key/value保存到hash结构中。以后resin检查session超时的线程每次检查时都要查看每个垃圾session,看是否超时。

  3. 垃圾session增加正常获取session的开销

  前面提到垃圾session也是要保存hash结构中,request.getSesson()每次都要用jsessionid在这个hash结构中取一次数据。当垃圾session大量充斥时,获取当正常

  有用的session的时间也会增加,具体就要看这个hash结构的算法如何了。

  当前上述的测试都是建立在最苛刻最恶劣的情况下,大多数情况我们的系统不会这么糟糕,也不是每个系统都对访问量/性能有高要求。如果觉得可以浪费的起,那浪费好了,只是我这边系统的情况不同,我们的产品对性能很敏感,能省就省点。

  除考虑性能外, session的创建在我们新设计的系统中,是必须非常严格控制的.这个和我们目前的系统结构,包括部署/用户身份认证有关.简单的说我们的系统是基于apache + resin的多机分布, 各个功能模块是作为不同的webapp发布的,session的生成和jsessionid的传递必须可控,因此我必须严格掌控系统中session的生成情况。

  另外说一点个人意见,知不知道有这些session自动创建的情况,和决定是否要在自己的代码中严格控制session创建,不是同一个概念。完全可以在了解情况后,根据自己的实际需要和个人习惯去做决定,比如选择无视。但是如果不知道呢?呵呵,很惭愧,在这次探索之前,我对jsp/webwork标签自动生成session是没有概念的,我们的原有系统是不使用HttpSession的(和当时的分布式方案有关),但是现在看来,由于jsp/webwork标签的存在,其实每次都有session被创建,这些session也就成了我上面说的垃圾session: 在不需要创建时意外创建,从来不使用,除了浪费资源外没有其他存在价值。

  如果当时能了解这些就好了,呵呵。了解后选择用与不用,和无知的情况下乱用,有差别的。

0
相关文章