Session简介
是什么?
- Session在网络中表示“会话控制”,用于存储特定用户所需的属性和其他的配置信息;
- Session表示一个特定的时间间隔,可以指用户从登陆系统到注销退出系统之家的时间。
为什么出现?
因为http 是一种无状态协议,如果没有Session的话,服务器无法识别请求是否来自同一个用户! 在一些业务场景中需要知道前面的操作和后台的操作是不是同一个用户的行为,即业务之间是有关联性的。
怎么用?
使用Session结合浏览器Cookie,将服务器Session保存到浏览器cookie中,这样可以保持http会话状态。 Session服务器创建,如Tomcat,浏览器发起请求到Tomcat服务器,然后Tomcat服务器生成SessionId保存在内存中,并将SessionId返回给浏览器,浏览器通过Cookie保存SessionId信息,用户每次通过浏览器访问服务器都会带上SessionId信息,这样就可以判断每次的请求是不是同一个用户,解决http协议无状态问题。
什么是Session一致性问题
单机版的系统,比如一个Tomcat部署,是不存在Session一直性的问题,因为Session保存在一个Tomcat容器中。
Session一致性问题是由架构演进或者业务的演进中发生,从单机演进到集群或者分布式的架构
用户---> 浏览器 ----> Nginx(轮询) -----> n(多)台Web服务器
比如Nginx使用轮询方式,用户第一次请求,请求被分配到到了 A web服务器,用户在A web服务器上进行登录,并保存登录信息(Session信息),并将Session信息响应给浏览器。当用户第二次在请求的时候 通过轮询会定位到B web服务器,此时B web服务器上没有 用户的登录信息(Session信息),则会提示用户进行登录,此时用户就会很萌B!
上面的描述就是一种产生Session不一致的例子。
Session一致性问题的解决方案
方案1
使用Nginx的ip_hash策略来做负载均衡
ip_hash策略的原理:根据Ip做hash计算,同一个Ip的请求始终会定位到一台web服务器上。
用户---> 浏览器 ----> Nginx(ip_hash) -----> n(多)台Web服务器
同一个用户(Ip)---> 浏览器 ----> Nginx(ip_hash) -----> A Web服务器
此时假如用户IP为 192.168.1.110 被hash到 A web服务器,那么用户的请求就一直会访问A web服务器了。
优点:
- 配置简单,只需要在Nginx中配置好ip_hash 策略
- 对应用无侵入性,应用不需要改任何
- ip_hash策略会很均匀的讲用户请求的ip分配到web服务器上,并且可以动态的水平扩展web服务器(只需在配置中加上服务器即可)
缺点:
假如有一台Tomcat 宕机或者重启,那么这一台服务器上的用户的Session信息丢失,导致单点故障。
方案2
使用服务器Session复制
服务器Session复制原理:Web服务器器创建Session后,会通过组播方式把Session发送到组播地址中的其他服务器上
用户---> 浏览器 ----> Nginx(轮询) -----> n(多)台Web服务器 (Session复制)
Tomcat的server.xml配置
<Cluster className="org.apacche.catalina.ha.tcp.simpleTcpCluster"/>
//tomcat session会话复制
优点:
- 对应用的侵入性有一点(应用中web.xml需要加上 标识是分布式的。对应该有侵入性。),但是还是比较小。
- Nginx可以配置轮询和ip_hash,能够适应各种负载均衡策略
- 一个Tomcat宕机不会影响Session丢失问题,解决了ip_hash 的问题
缺点:
- Session同步会有延迟,会影带宽
- 受限于内存资源,在大用户量,高并发,高流量场景,会占用大量内存,不适合!
- 增加服务器不灵活,不易于扩展
- 服务器重启后会有问题
方案3
使用Session集中统一管理
使用Session集中统一管理原理: Session不在由web服务器管理,而是统一放到一个地方集中式管理,读取和写入Session都依赖第三方软件。例如Redis、MongoDB、mysql等
用户---> 浏览器 ----> Nginx(轮询) -----> n(多)台Web服务器 ----> redis(集群)
优点:
- 扩展能力强
- 服务器宕机后Session不会丢失
缺点:
- 对应用有侵入性,要增加一些配置文件
- 需要依赖第三方的库
- 需要搭建Redis的服务
应用场景:互联网项目,大型分布式、大并发场景下,首先方案!