始终对 Session 和 Cookies 的应用有点困惑,趁手上有个小需要用到了的机会学习一下。
基础知识
1. 因为 http 协定是无状态的协定,为了可能记住申请的状态,于是引入了 Session 和 Cookie 的机制。
2.Session 是存在于服务器端的,在单体式利用中,由 Tomcat 治理,而 Cookie 则是存在于客户端,更不便了解的说法,能够说存在于浏览器。
3.Cookie 只是实现 Session 的其中一种计划。尽管是最罕用的,但并不是惟一的办法。
4. 流程
- 首先,客户端会发送一个 http 申请到服务器端。
- 服务器端承受客户端申请后,建设一个 session,并发送一个 http 响应到客户端,这个响应头,其中就蕴含 Set-Cookie 头部。该头部蕴含了 sessionId。
- 在客户端发动的第二次申请,如果服务器给了 set-Cookie,浏览器会主动在申请头中增加 cookie
- 服务器接管申请,合成 cookie,验证信息,核查胜利后返回 response 给客户端
代码示例
1. 如果没有调用 request.getSession()办法,那么服务器永远都不会创立 JSESSIONID。
2. 如果调用 request.getSession()办法那么状况分为以下两种状况:
- 如果是第一次拜访,那么 request.getSession()会创立一个 JSESSIONID,并且在响应头外面有设置:
Set-Cookie:JSESSIONID=********************************; Path=/; HttpOnly
- 如果不是第一拜访,那么此次浏览器拜访该项目标时候,申请头会带有:
Cookie:JSESSIONID=*********************************
request.getSession()会先去获取申请头的 JSESSIONID,并且在服务器外面查找该 ID,如果该 session 对象还存活(tomcat 默认 session 的存活工夫为 30 分钟,过了 30 分钟后,该 session 对象会被销毁)则间接获取该 session,如果该 session 曾经被销毁了,则从新又创立一个 session 对象
分布式状况下的 Session
通过一个 ngxin 的负载平衡拜访来阐明下存在的问题。
1. 启动一个 nginx,负载平衡拜访到 8080,8081 两个服务
2. 首先拜访到了 8080,带回了 set-cookies 命令和 sessionID
3. 拜访 getName 接口,因为 nginx 的负载平衡,此时拜访到了 8081
因为 Session 是存储在了 Tomcat 上的,而当初是两个 Tomcat,所以 Session 是不同的!
整合 spring-session-data-redis
首先拜访到了 8080,带回了 set-cookies 命令和 sessionID
查看 redis
拜访 getName 接口,因为 nginx 的负载平衡,此时拜访到了 8081, 此时没有再生成新的 sessionId
Demo: https://github.com/WillLiaowh…