聊一聊 Session 和 Cookie

2年前 (2022) 程序员胖胖胖虎阿
240 0 0
Session和Cookie可是我们的老熟人了,不过这两个老熟人可是不怎么好相处,又熟悉又陌生,又简单又复杂,都非常的令人头疼,就连很多有一定工作经验的人也觉得是块硬骨头;
说他们熟悉,是因为天天和他们打交道,说陌生是因为根本就不了解他们,就如同天天住在一起但是不怎么说话的邻居,天天见也就是混了个脸熟,可能连人家干啥的都不知道;
说简单是因为他们本身只是HTTP中的一个配置项,在Servelt规范中也只是应用到一个类而已,说他们复杂主要是数量引起的,很多小问题一旦到达一定的数量就会成为一个大问题;
现在我们的系统已经大到要用到很多Cookie了,我们必须要考虑HTTP如何解决由于他们的数量和大小带来的瓶颈问题;同时还会用到很多的Session,如何解决Session与多套服务器之间的共享问题?还有,安全问题也不容忽视;

Session和Cookie的主要作用在于完成用户与服务器之间的交互,他们有各自的优点和缺点,但是令人更加头疼的是,他们的优点居然和他们的使用场景是矛盾的!

Cookie

到底什么是Cookie?

官方解释是:一个用户通过HTT访问一个服务器时,被访问的服务器会把一些加上限制条件的key/value键值对返回给客户端,用户下一次访问并且条件也符合的时候,数据又被完整的带回给了服务器;
用人话来说就是:疫情期间出入小区需要登记信息,每次出入都要登记一遍非常麻烦,于是小区委员会就给业主们发了一张记录着个人健康信息、行程等信息的信息卡,下次只要出入时出示信息卡就可以了,不必登记,这个信息卡就是Cookie!
W3C在设计Cookie的时候是这样考虑的:用户在一段时间内访问Web应用的行为路径,我们都知道HTTP是一种无状态协议,也就是说,用户在完成一次服务请求之后再访问一次,服务器是不知道这两次是不是同一个人的;
服务器能不能知道是不是同一个人访问了数据是非常重要的,因为这个涉及到了性能的优化,如果一个用户频繁地访问几条数据,就可以针对这几台数据做个缓存,缓存的思想在计算机当中的重要性堪比CPU;
Cookie的作用就相当于充当了一个缓存,只要是同一个用户(客户端) 请求并且每次请求都带有第一次访问时的服务端设置的信息,那么服务端就可以根据Cookie值来划分用户,从而提高数据访问的效率;

Cookie是如何为我们服务的?

我们通常都是用这种方式来创建Cookie:

聊一聊 Session 和 Cookie聊一聊 Session 和 Cookie

即使没有设置版本号,Tomcat也会在最后创建HTTP响应头的时候自动把Version的版本设置为1,这是Tomcat创建Set-Cookie的时序图:

聊一聊 Session 和 Cookie

在这里要注意几点:
1.当Cookie的属性项里出现Version为1的属性项时,构建HTTP响应头同样会把Version设置为1;

2. 当Name和Value的值出现一些Token字符的时候,构建返回头会把该Cookie的Version设置为1;

3. 创建Cookie的时候,Name必须与set-Cookie(或者是set-Cookie)的属性值一样;

4. Name和Value的值不能设置成ASSIC字符

Session

Session是干嘛的?

前面说过,Cookie可以让服务端跟踪客户端的访问,每次客户端的访问都需要返回一个Cookie,如果Cookie太多的话就会增加数据传输的负担,那这个负担由谁来抗下呢?

就是Session,它的出现就应了一句话:哪有什么岁月安好,只是有人替你负重前行;

再补充一点:同一个客户端与服务端交互的时候不需要每次都传回Cookie值,取而代之的是ID,这个ID是客户端第一次访问服务端的时候生成的,而且每个客户端都是唯一的,所以每个ID都是唯一的,就如同我们都有唯一的指纹一样,这个ID通常是Name为JSESIONID的一个Cookie;

关于Session工作原理的前期准备

Session有三种工作方式:

聊一聊 Session 和 Cookie

Session是怎么干活的?

有了SessionID服务端就可以创建HttpSession对象了,不过第一次触发的时候需要通过request.getSession()函数,如果当前的SessionID还没有对应的HttpSession对象那就创建一个新的,然后把这个对象添加到org.apache.catalina.Manage的Session容器中保存起来;
从Request中获取的Session对象保存在了org.apache.catalina.Manager类中,这个类是个抽象类,他的实现类是org.apache.catalina.session.StandardManager,通过requestedSession从StandardManager的sessions集合中取出StandardSession对象;
因为Manager类是管理着Session全部生命周期的,Session一旦过期,就会被回收,服务器也会关闭,Session将会被序列化到磁盘啊,HttpSession对象存在,用户就可以根据SessionID来获取,这就叫做状态的保持,一个requestSession对应一个访问的客户端,一个  客户端也对应着一个保存着我们创建的Session值得StandardSession对象;
StandardManager类负责Servelt容器中所有的StandardSession对象的生命周期管理,当Servelt容器重启或者是关闭的时候,StandardManager负责把还没有过期的StandardSession的对象给持久化到“SESSIONS.ser”文件;
当StandardManager初始化时(也就是Servlet容器重启的时候)会重新读取“SESSIONS.ser”文件并解析出所有的Session对象,重新保存在StandardManager的Session集合中;
这是Session的恢复状态图:

聊一聊 Session 和 Cookie
Servelt容器关闭之后,StandardManager类就会调用unload()函数把Session集合中的StandardSession对象写入到

%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%22%26lt%3Bh2%26gt%3B%E6%A3%80%E6%9F%A5%E6%81%A2%E5%A4%8D%E7%9A%84session%E6%98%AF%E5%90%A6%E8%BF%87%E6%9C%9F%26lt%3B%2Fh2%26gt%3B%22%20style%3D%22rounded%3D1%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfillColor%3D%23dae8fc%3BstrokeColor%3D%236c8ebf%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22250%22%20y%3D%22190%22%20width%3D%22120%22%20height%3D%2260%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E“SESSIONS.ser

文件中,注意在持久化Selvelt容器中的Session对象时千万不能直接kill掉Servelt容器的进程,而是必须调用Servelt容器中stop和start命令来完成,一旦把进程结束了就不能做持久化了;
再补充一点:天下没有不散的筵席,StandardManager的Session集合中的StandardSession对象并不是永远保存,要不然Servelt容器的内存就会被撑爆的,所以每一个Session对象都有个有效时间,一点超时就会被清除,在Tomcat(由backgroundProcess()函数进行检查)中这个有效时间是60s;

这是过期session状态图:

聊一聊 Session 和 Cookie

不过,哪怕是与客户端关联的Session对象都过期了,request.getSession()函数调用的StandardSession也会一直存在,Session对象过期了咋办?重新建立一个全新的StandardSession对象(注意,之前设置的Session值不会存在了);
分布式Session框架能干点啥?

先来看一下都主要存在哪些问题:

  1. 客户端Cookie存储限制。

  2. Cookie管理混乱

  3. 安全性也不是很好

那分布式Session框架都能解决什么呢,或者说他有哪些优点?

  1. Session配置的统一管理

  2. Cookie使用的监控和统一规范管理

  3. Session存储的多元化

  4. Session配置的动态修改

  5. Session的key的定期修改

  6. 有着很好的容灾机制,框架的稳定性比较好

  7. 拥有对存储的监控以及报警支持

  8. 拥有可扩展性,能够兼容更多的Session机制

  9. 跟够解决跨域名Session与Cookie之间共享的问题

分布式Session框架是怎么干活的呢?一图胜千言

聊一聊 Session 和 Cookie

总结

这就是好基友Cookie和Session相爱相杀的故事,不是,使他们一起为人类的互联网世界做贡献的故事,很多技术的研发都是为了解决量的增长带来的问题,Cookie和Session就是其中之二,我忽然想起以为计算机先贤说过的就一句话,大致意思是互联网的神奇之处就在于,他其实视为千千万万的人服务的,然而却像是专门为你一个人服务似的,我想这离不开很多像Cookie和Session这样的技术的支持!


推荐阅读
1. 
GitHub 上有什么好玩的项目?
2.  
6 月份最热 GitHub 盘点
3.  
摸鱼王
4. 100 道 Linux 常见面试题

聊一聊 Session 和 Cookie

本文分享自微信公众号 - Java后端(web_resource)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

版权声明:程序员胖胖胖虎阿 发表于 2022年10月8日 下午2:32。
转载请注明:聊一聊 Session 和 Cookie | 胖虎的工具箱-编程导航

相关文章

暂无评论

暂无评论...