分布式下session一致性架构全解

什么是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

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster 
channelSendOptions="8">
//8异步发送
<Manager ... session.BackupManager
<Membership address="228.0.0.4"
<Receiver address="auto" port="5001"

tomcat2 server.xml

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster 
channelSendOptions="8">
//8异步发送
<Manager ... session.BackupManager
<Membership address="228.0.0.4"
<Receiver address="auto" port="5002"

web.xml

<distributable/>

优点:应用侵入性低,能适应各种负载均衡策略,tomcat宕机不存在session丢失 
缺点:session同步延迟,受限于内存资源,大量占用内存和带宽,不利于水平扩展

 

方案三: Session集中统一管理

原理:Session不由tomcat管理,而是统一放到一个地方集中式管理, 读取和写入Session都依赖第三方软件。例如redis,mongodb,mysql等。

添加依赖 
spring-session

spring-session-data-redis

redis

jedis

web.xml 配置Filter

<filter>
  <filter-name>springSessionRepositoryFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</fitler-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

spring-applicationContext.xml:

<bean id="redisHttpSessionConfiguration" 
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfig 
<property name="maxInactiveIntervalInSeconds" value="600"/>

<bean id="jedisPoolConfig"

<bean id ="jedisConnectionFactory"

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数据 

posted @ 2019-01-13 22:20  Java菜得抠脚  阅读(523)  评论(0编辑  收藏  举报