一直对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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。