什么是Session?
what
Session在网络应用中表示"会话控制",用于存储特定用户会话所需的属性及配置信息;Session又表示一个特定的时间间隔,指从注册登陆进入系统到注册退出系统之间所经过的时间。
why
http是无状态的协议
在动态web应用中,往往需要知道前面的操作和后面的操作是不是同一用户。也就是业务需要有关联性的。
how
结合Session和游览器cookie,将服务端Session保存到游览器cookie中来保持http会话状态。
什么是Session一致性问题?
只要用户不重启浏览器,每次http短连接请求,理论上服务端都能定位到session,保持会话。
Session一致性问题解决方案
方案一: 基于nginx的ip_hash策略来做负载均衡
原理:根据ip做hash计算,同一个ip的请求始终会定位到同一台tomcat
nginx配置
upstream sessionTest {
ip_hash;
server 192.168.2.177:801;
server 192.168.2.177:802;
}
niginx 命令
start nginx
nginx-s reload
优点:配置简单,应用没有兼容性的,均匀的 ,便于水平扩展
缺点:存在单点故障,会导致部分服务不可用
方案二:服务器Session复制
原理:Tomcat服务器创建Session后,会通过组播方式把Session发生到组播地址中的其他服务器上
tomcat1 server.xml
//8异步发送
tomcat2 server.xml
//8异步发送
web.xml
优点:应用侵入性低,能适应各种负载均衡策略,tomcat宕机不存在session丢失
缺点:session同步延迟,受限于内存资源,大量占用内存和带宽,不利于水平扩展
方案三: Session集中统一管理
原理:Session不由tomcat管理,而是统一放到一个地方集中式管理, 读取和写入Session都依赖第三方软件。例如redis,mongodb,mysql等。
添加依赖
spring-session
spring-session-data-redis
redis
jedis
web.xml 配置Filter
springSessionRepositoryFilter
org.springframework.web.filter.DelegatingFilterProxy
springSessionRepositoryFilter
/*
spring-applicationContext.xml:
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfig
config.properties
reids.hostname=192.168.2.227
redis.port=6379
redis.timeout=3000
redis.pool.maxTotal=100
redis.pool.maxIdle=10
redis命令
修改redis.windows.conf
bind 0.0.0.0
redis-server.exe redis.windows.conf
redis-cli.exe -h 192.168.2.227
keys *
type
hgetall key
注意:session中的对象必须可序列化。
优点:扩展能力强,session不易丢失,适应各种负载均衡策略,
缺点:依赖第三方软件,有应用侵入性;
无法实现跨域名共享session , 只能在单台服务器上共享session , 因为是依赖cookie做的 , cookie 无法跨域;一般是用于多台服务器负载均衡时共享Session的,都是同一个域名,你想要的跨域的登录,可能需要SSO单点登录。
应用场景:大型分布式环境首选。
spring-session原理
spring-session本质:覆盖原有tomcat 容器的HttpSession实现。
org.springframework.web.filter.DelegatingFilterProxy 在请求之前 覆盖tomcat 的httpsession实现,具步骤:
1、SessionRepositoryFilter和JedisConnectionFactory注册过程
2、SessionRepositoryFilter添加到FilterChain
3、SessionRepositoryFilter拦截过程
4、SessionRepository保存session数据