0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

分布式Session一致性及其作用

马哥Linux运维 来源:SimpleWu 2023-03-14 15:07 次阅读

分布式Session一致性?

说白了就是服务器集群Session共享的问题

Session的作用?

Session 是客户端与服务器通讯会话跟踪技术,服务器与客户端保持整个通讯的会话基本信息

客户端在第一次访问服务端的时候,服务端会响应一个sessionId并且将它存入到本地cookie中,在之后的访问会将cookie中的sessionId放入到请求头中去访问服务器,如果通过这个sessionid没有找到对应的数据那么服务器会创建一个新的sessionid并且响应给客户端。

分布式Session存在的问题?

假设第一次访问服务A生成一个sessionid并且存入cookie中,第二次却访问服务B客户端会在cookie中读取sessionid加入到请求头中,如果在服务B通过sessionid没有找到对应的数据那么它创建一个新的并且将sessionid返回给客户端,这样并不能共享我们的Session无法达到我们想要的目的。

解决方案:

使用cookie来完成(很明显这种不安全的操作并不可靠)

使用Nginx中的ip绑定策略,同一个ip只能在指定的同一个机器访问(不支持负载均衡)

利用数据库同步session(效率不高)

使用tomcat内置的session同步(同步可能会产生延迟)

使用token代替session

我们使用spring-session以及集成好的解决方案,存放在redis中

目前项目中存在的问题

启动两个项目端口号分别为8080,8081。

依赖:

 

org.springframework.boot
spring-boot-starter-parent
2.1.1.RELEASE
 


 

org.springframework.boot
spring-boot-starter-web


创建测试类:

/**
*Author:SimpleWu
*date:2018/12/14
*/
@RestController
publicclassTestSessionController{

@Value("${server.port}")
privateIntegerprojectPort;//项目端口

@RequestMapping("/createSession")
publicStringcreateSession(HttpSessionsession,Stringname){
session.setAttribute("name",name);
return"当前项目端口:"+projectPort+"当前sessionId:"+session.getId()+"在Session中存入成功!";
}

@RequestMapping("/getSession")
publicStringgetSession(HttpSessionsession){
return"当前项目端口:"+projectPort+"当前sessionId:"+session.getId()+"获取的姓名:"+session.getAttribute("name");
}

}

yml配置:

server:
port:8080

修改映射文件

#将本机ip映射到www.hello.com上
127.0.0.1www.hello.com

在这里我们开启nginx集群,修改配置:

#加入
#默认使用轮询,
upstreambackserver{
server127.0.0.1:8080;
server127.0.0.1:8081;
}
#修改server中的local
location/{
proxy_passhttp://backserver;
indexindex.htmlindex.htm;
}

我们直接通过轮询机制来访问首先向Session中存入一个姓名,http://www.hello.com/createSession?name=SimpleWu

“当前项目端口:8081 当前sessionId :0F20F73170AE6780B1EC06D9B06210DB在Session中存入成功!

因为我们使用的是默认的轮询机制那么下次肯定访问的是8080端口,我们直接获取以下刚才存入的值http://www.hello.com/getSession

“当前项目端口:8080 当前sessionId :C6663EA93572FB8DAE27736A553EAB89 获取的姓名:null

这个时候发现8080端口中并没有我们存入的值,并且sessionId也是与8081端口中的不同。

别急继续访问,因为轮询机制这个时候我们是8081端口的服务器,那么之前我们是在8081中存入了一个姓名。那么我们现在来访问以下看看是否能够获取到我们存入的姓名:SimpleWu,继续访问:http://www.hello.com/getSession

“当前项目端口:8081 当前sessionId :005EE6198C30D7CD32FBD8B073531347 获取的姓名:null

为什么8080端口我们没有存入连8081端口存入的都没有了呢?

我们仔细观察一下第三次访问8081的端口sessionid都不一样了,是因为我们在第二次去访问的时候访问的是8080端口这个时候客户端在cookie中获取8081的端口去8080服务器上去找,没有找到后重新创建了一个session并且将sessionid响应给客户端,客户端又保持到cookid中替换了之前8081的sessionid,那么第三次访问的时候拿着第二次访问的sessionid去找又找不到然后又创建。一直反复循环。

如何解决这两个服务之间的共享问题呢?

spring已经给我们想好了问题并且已经提供出解决方案:spring-session 不了解的可以去百度了解下。

我们首先打开redis并且在pom.xml中添加依赖:


com.alibaba
fastjson
1.2.47


org.springframework.boot
spring-boot-starter-data-redis

 

org.springframework.session
spring-session-data-redis


org.apache.commons
commons-pool2


redis.clients
jedis

修改yml配置文件:

server:
port:8081
spring:
redis:
database:0
host:localhost
port:6379
jedis:
pool:
max-active:8
max-wait:-1
max-idle:8
min-idle:0
timeout:10000
redis:
hostname:localhost
port:6379
#password:123456

添加Session配置类

/**
*Author:SimpleWu
*date:2018/12/14
*/
//这个类用配置redis服务器的连接
//maxInactiveIntervalInSeconds为SpringSession的过期时间(单位:秒)
@EnableRedisHttpSession(maxInactiveIntervalInSeconds=1800)
publicclassSessionConfig{

//冒号后的值为没有配置文件时,制动装载的默认值
@Value("${redis.hostname:localhost}")
privateStringhostName;
@Value("${redis.port:6379}")
privateintport;
//@Value("${redis.password}")
//privateStringpassword;

@Bean
publicJedisConnectionFactoryconnectionFactory(){
JedisConnectionFactoryconnection=newJedisConnectionFactory();
connection.setPort(port);
connection.setHostName(hostName);
//connection.setPassword(password);
//connection.setDatabase(0);
returnconnection;
}
}

初始化Session配置

/**
*Author:SimpleWu
*date:2018/12/14
*/
//初始化Session配置
publicclassSessionInitializerextendsAbstractHttpSessionApplicationInitializer{
publicSessionInitializer(){
super(SessionConfig.class);
}
}

然后我们继续启动8080,8081来进行测试:

首先存入一个姓名

“当前项目端口:8080 当前sessionId :cf5c029a-2f90-4b7e-8345-bf61e0279254在Session中存入成功!

应该轮询机制那么下次一定是8081,竟然已经解决session共享问题了那么肯定能够获取到了,竟然这样那么我们直接来获取下姓名

“当前项目端口:8081 当前sessionId :cf5c029a-2f90-4b7e-8345-bf61e0279254 获取的姓名:SimpleWu

这个时候我们发现不仅能够获取到值而且连sessionid都一致了。

实现原理:

就是当Web服务器接收到http请求后,当请求进入对应的Filter进行过滤,将原本需要由web服务器创建会话的过程转交给Spring-Session进行创建,本来创建的会话保存在Web服务器内存中,通过Spring-Session创建的会话信息可以保存第三方的服务中,如:redis,mysql等。Web服务器之间通过连接第三方服务来共享数据,实现Session共享!





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    12

    文章

    9119

    浏览量

    85311

原文标题:分布式 Session 解决方案

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    一致性测试系统的技术原理和也应用场景

    种有效手段。 综上所述,一致性测试系统的技术原理和应用场景都非常广泛和深入,在通信协议、网络设备和系统的验证以及企业系统数据校验等方面发挥着重要作用
    发表于 11-01 15:35

    行代码,保障分布式事务一致性—GTS:微服务架构下分布式事务解决方案

    解决方案----GTS。该方案中提到的GTS是目前业界第款,也是唯款通用的解决微服务分布式事务问题的中间件,而且可以保证数据的强一致性
    发表于 06-05 19:14

    一致性规划研究

    针对一致性规划的高度求解复杂度,分析主流一致性规划器的求解策略,给出影响一致性规划器性能的主要因素:启发信息的有效,信念状态表示方法的紧凑
    发表于 04-06 08:43 12次下载

    蓝鲸集群文件系统中资源交互一致性协议

    在蓝鲸集群文件系统中,分布式资源交互在系统异常的情况下会出现资源状态不一致的情况,为解决这问题,该文提出分布式资源交互一致性协议S2PC-
    发表于 04-21 09:24 12次下载

    一致性新型锁同步机制的实现

    一致性新型锁同步机制的实现将软件分布式共享存储系统所使用的基于域一致性协议锁机制以新的方式加以实现。它充分利用SMP 结构所具有的特点,以多级方式实现锁同步机制
    发表于 09-02 10:27 12次下载

    DBA迅速解决分布式事务XA一致性问题

    DBA迅速解决分布式事务XA一致性问题
    发表于 09-07 14:45 3次下载
    DBA迅速解决<b class='flag-5'>分布式</b>事务XA<b class='flag-5'>一致性</b>问题

    分布式一致性算法Yac

    传统静态拓扑主从模型分布式一致性算法存在严重负载不均及单点性能瓶颈效应,且崩溃节点大于集群规模的50qo时算法无法正常工作。针对上述问题,提出基于动态拓扑及有限表决思想的分布式一致性
    发表于 11-27 17:49 0次下载
    <b class='flag-5'>分布式</b><b class='flag-5'>一致性</b>算法Yac

    基于消息通信的分布式系统最终一致性平台

    分布式系统中为了满足高性能和吞吐量,般采用异步消息通信方式,但消息通信没有解决分布式事务不一致问题。针对这个问题,提出建立一致性保障平台
    发表于 12-04 16:15 0次下载
    基于消息通信的<b class='flag-5'>分布式</b>系统最终<b class='flag-5'>一致性</b>平台

    分布式大数据不一致性检测

    不高;而分布式环境下不一致性检测更富有挑战,不仅需要考虑数据的迁移,检测任务如何分配也是个难题.在大数据背景下,上述问题更加突出.提出了
    发表于 01-12 16:29 0次下载

    一致性哈希是什么?为什么它是可扩展的分布式系统架构的个必要工具

    在本文中,我们将了解一致性哈希是什么、为什么它是可扩展的分布式系统架构中的个必要工具。
    的头像 发表于 07-17 17:57 4390次阅读

    基于自触发一致性算法的分布式分层控制策略

    针对传统下垂控制及线路阻抗不匹配等因素引起的孤岛微电网电压偏差及无功功率难以均分的问题,提出基于自触发一致性算法的分布式分层控制策略。在微电网二次控制层采用一致性算法构造电压、无功功率全局平均值估计
    发表于 03-24 15:35 9次下载
    基于自触发<b class='flag-5'>一致性</b>算法的<b class='flag-5'>分布式</b>分层控制策略

    种更安全的分布式一致性算法选举机制

    目前应用于分布式系统中的基于选举的分布式一致性算法(类 Paxos算法),都是采用得到50%以上选票者当选 Leader的方式进行选举。此种选举机制类似现实生活中的选举,存在因控制投票而丧失系统去
    发表于 04-07 10:29 9次下载
    <b class='flag-5'>一</b>种更安全的<b class='flag-5'>分布式</b><b class='flag-5'>一致性</b>算法选举机制

    最终一致性是现在大部分高可用的分布式系统的核心思路

    这篇文章我们聊分布式相关的内容。 提到分布式系统,就定绕不开“一致性”,这次我们说说:最终一致性。 最终
    的头像 发表于 06-17 14:40 1875次阅读

    为什么需要分布式共识算法

    满足CAP理论,而 分布式共识算法解决的就是CAP理论中的一致性问题。整个一致性问题分为三种问题: 顺序一致性 线性一致性 因果
    的头像 发表于 11-10 10:18 567次阅读
    为什么需要<b class='flag-5'>分布式</b>共识算法

    分布式系统中常见的一致性模型

    什么是一致性模型? 在分布式系统中,C(一致性) 和 A(可用)始终存在矛盾。若想保证可用,就必须通过复制、分片等方式冗余存储。而
    的头像 发表于 11-10 11:33 926次阅读
    <b class='flag-5'>分布式</b>系统中常见的<b class='flag-5'>一致性</b>模型