cookie和session
不同的浏览器对于服务器来说就是不同的用户,假如现在有ab两个不同的浏览器访问服务器,a、b两个浏览器所携带的sessionid的值肯定不一样,但是其key值一样,都是JSESSIONID
那么持久化session(这里指seesionId的值推送到cookie的方案)时,服务器tomcat是怎么区别哪个sessionid对应哪个浏览器用户呢?
答案可以在源码中找一下:
Manager manager = context.getManager();
if (manager == null) {
return (null);
}
if (requestedSessionId != null) {
try {
session = manager.findSession(requestedSessionId);
} catch (IOException e) {
session = null;
//有效判断主要为session存活时间
}
if ((session != null) && !session.isValid()) {
session = null;
}
if (session != null) {
session.access();
return (session);
}
}
而其关键点在于session = manager.findSession(requestedSessionId)
好,下面进一步分析:
假如A浏览器的sessionid为aaaaaa,生命周期是默认设置时间30分钟;
- situation1:客户端cookies死了(客户在30分钟内手动删除cookie信息)
那么,客户端去访问服务器端的时候,服务器从cookie中找不到SESSIONID,会生成一个新的session,假设其id为bbbbbb;此时服务器内内其实还有sessionid为aaaaaa的数据,这个sessionid=aaaaaa此时会处于游离态,直到其生命周期结束,才会杀死(在此期间会消耗无畏的资源) - sitaution2:客户端cookie没死(但是cookies的生命周期比session的生命周期长,且在此访问时超过30分钟)
那么,客户端去访问服务器端的时候, 可以从cookie中解析出sessionid但是在服务器已经找不到对应的session信息了(因为已经超过其生命周期,被垃圾回收机制杀死了),服务器会新创造一个session
得出结论:
cookie的生命周期设置的时间一般比session的生命周期要长,避免服务器资源闲置(客户故意杀死session不算,因为我们无法干预客户端的操作)
好,我们接下来继续分析
考虑到大部分客户是不会手动清除cookie信息的,为了提高客户体验,是不是可以将session(当然包括sessionid)数据放到数据库中,同时将session和cookie的生命周期时长都设置的长一些呢?这样当客户经过比较长的一段时间,客户端的sessionid在服务器端还是可以到,那么用户之前的数据也就跟着带出来了。
然而,事实上 客户可能在电脑上有多个浏览器,也可能在不同的电脑上访问过该服务器,此时不可避免的会产生一些脏数据,服务器数据会越来越多,然后大数据便产生了,我想这可能也是原因之一吧!!!
所以,cookie的生命周期可能会设置很长,但是session的生命周期相对来说不会太长,只要用户在一定时间内再次访问我服务器,我服务器给session刷新生命周期就可以了,否则,客户对我来说就是僵尸用户,我就没必要对你客气了,直接杀死session数据就行了,对吧?
然后,我们再进一步分析
为了缓解服务器压力,我们会考虑用分布式集群,为了使不同的服务器被均匀访问,我们会负载均衡,或者用zookeeper或者用nginx,不管用哪个吧,问题是不同的服务器怎么识别用户这个session信息呢?
- answer1:有一个专门的服务器存储session信息
问题:如果存储session的服务器宕机了呢?岂不是一场大灾难吗? - answer2:整个分布式系统中,每个服务器会以某种方式,同步session数据,也就是每个服务器都会保存一份session
问题:按照上面的分析,session的数据会很大,13亿人,每人按一台电脑算,每台电脑不可能只有一个浏览器吧,更何况人均应该是超过1台电脑的,那么光session的数据就海的去了,这种方案也是不是很好呀?(ps:针对大公司而来,小公司无所谓了)
总结:困惑,困惑,还是困惑?求解答?
难道我们为了session会做一个专门的集群吗?