1

一直对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给客户端

image.png

代码示例

image.png
image.png
image.png

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两个服务
image.png
image.png
2.首先访问到了8080,带回了set-cookies命令和sessionID
image.png
3.访问getName接口,由于nginx的负载均衡,此时访问到了8081
image.png
因为Session是存储在了Tomcat上的,而现在是两个Tomcat,所以Session是不同的!

整合spring-session-data-redis
image.png
image.png
image.png
首先访问到了8080,带回了set-cookies命令和sessionID
image.png
查看redis
image.png
访问getName接口,由于nginx的负载均衡,此时访问到了8081,此时没有再生成新的sessionId
image.png

Demo: https://github.com/WillLiaowh...


WillLiaowh
71 声望8 粉丝

世界上最伟大的力量是坚持。