暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

每日一学之session、sessionid、jsessionid与cookie

程序员的日记本 2018-05-22
1144


今天的文章将帮助大家明白什么是会话?session失效又是什么意思?cookie又是什么?cookie与session又是什么关系?什么又是sessionId?


ServletRequestListener


通过实现此接口,可以监控到Request的生命周期,我们可以发现当一个request请求处理完成之后,就被销毁了。

public class CSRequestListener implements ServletRequestListener {

   public void requestDestroyed(ServletRequestEvent arg0) {
       System.out.println("request被注销了");

   }

   public void requestInitialized(ServletRequestEvent arg0) {
       System.out.println("request被创建了");
   }

}


request被创建了
传递的参数:2
request被注销了


HttpSessionListener


通过实现此接口,我们可以监控到session的生命周期,且可以通过修改web.xml文件中的session-config标签来设置过期时间。

public class CSSessionListener implements HttpSessionListener {

   public void sessionCreated(HttpSessionEvent arg0) {
       System.out.println(activeTime() + " session被创建了");
       HttpSession session = arg0.getSession();
       System.out.println("sessionId: "+session.getId());
   }

   public void sessionDestroyed(HttpSessionEvent arg0) {
       System.out.println(activeTime() + " session被销毁了");
   }

   public String activeTime() {
       return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis());
   }

}


<!--1分钟后session过期-->
<session-config>

  <session-timeout>1</session-timeout>
</session-config>


###############第一次访问执行结果#############
request被创建了
传递的参数:2
2018-05-21 15:44:17 session被创建了
sessionId: 393EAA87E183A4ECC1B686E43AC6CE86
request被注销了

2018-05-21 15:45:22 session被销毁了


Cookie


cookie除了浏览器会自动生成外,服务端也可以自定义cookie的内容和过期时间

Cookie token = new Cookie("token" , "JIJL8320JFLKDSADUD");
token.setMaxAge(60 * 24);//一天
response.addCookie(token);


Cookie And Session


通过打开firefox的调试界面,注意下面的内容,神奇的事情就要发生了


请大家看上图中的1,这个是响应头中的JSESSIONID(JSESSIONID是tomcat的叫法,其余可能不叫JSESSIONID),但是在请求头中却没有。那我们再看看这个JSESSIONID与服务端的sessionid有什么关系呢?


不知道大家发现了没有,服务端的sessionId就是响应头里面的JSESSIONID。OK,我们再来刷新一次页面,神奇的事情再次发生了



对,没错,响应头中的JSESSONID消失了,但是在请求头里面的JSESSIONID的值变为了第一次响应头的JSESSIONID的值了。


因此我们大胆推测,当tomcat第一次获取到cookie中的JSESSIONID的时候,发现并没有JSESSIONID,因此就创建一个JSESSIONID,并利用response.addCookie的方式返回给客户端,后面每一次访问服务端的时候,浏览器就将这个JSESSIONID传递到服务端来判断合法性。


多服务器session问题


大家可以想一下,在相同浏览器下访问经过负载均衡的两个tomcat服务器,会出现什么情况?


第一次:访问Tomcat-A,Tomcat-A发现没有此次会话的JSESSIONID,然后重新创建了一个JSESSIONID,并通过cookie返回;


第N次:访问Tomcat-B,Tomcat-B同样会发现这个JSESSIONID没有相应的session信息,OK,就会再次创建一个JSESSIONID,并返回浏览器。


第N+1次:再次访问Tomcat-A的时候,发现在服务器上的找不到JSESSIONID相应的session,但是对用户来说确是一次未退出的访问。


问题:这样就会导致当负载均衡服务器自动切换的时候,session会失效。


思考


保证两个服务器收到的JSESSIONID一致,是否就可以解决负载均衡环境下由于session不一致导致的访问失败的问题?


下期提要


下期我们将主要分享怎么样解决负载均衡环境下的SESSION共享问题。



近期,我和活跃在业界的一线技术老司机们共同开通了知识星球,——一个与公众号有别,但又一脉相承的技术圈、认知圈:公众号会一如既往地进行知识分享,知识星球则坚持关注解决问题与动手实践。问题很广、方法很多、思绪很快,希望我们能够在这里驻足思考、交流、沉淀、提升。


你负责认真,我们负责帮你解决问题,让改变发生;欢迎大家扫码加入我们的星球。期待 2018,在程序猿成长的道路上,彼此成就,共同进化!

文章转载自程序员的日记本,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论